Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Set Up GitOps with ArgoCD

By Kokil Thapa | Last reviewed: September 2026

You want to Set Up GitOps with ArgoCD so Kubernetes deployments stop depending on manual kubectl apply runs and one-off shell scripts. Git becomes the single source of truth. Argo CD watches your repo and keeps the cluster aligned with what is committed. This guide walks through a production-minded setup: install the controller, connect a Git repository, define an Application, tune sync policy, and harden access. If you already run GitOps with Flux or Argo CD, much of the mental model transfers—the tooling differs.

What is GitOps and why should you Set Up GitOps with ArgoCD?

GitOps means every desired cluster state lives in version control. A controller reconciles live resources against that declared state. Push a commit, and the platform applies it. Drift gets corrected or flagged. Rollback is a git revert, not a frantic terminal session.

Argo CD is a CNCF-graduated continuous delivery tool built for Kubernetes. It reads Helm charts, Kustomize overlays, plain YAML, Jsonnet, or a mix. It renders manifests, compares them to live objects, and syncs when you allow it. The UI shows diffs, health, and history—useful when a small team owns both app code and cluster ops.

I have spent years on GitLab CI plus Deployer for PHP/Laravel stacks on bare metal and VMs. That model works well for monoliths. When workloads move to Kubernetes—microservices, sidecars, ingress, secrets operators—GitOps with Argo CD closes the gap between what Git says and what the cluster runs. For teams also shipping custom apps, pairing this with enterprise application development practices keeps deploy pipelines consistent end to end.

GitOps with Argo CD — Core LoopGit RepoSource of truthArgo CDReconcile engineKubernetesLive clusterContinuous reconciliationDetect drift → show diff → sync or self-healAudit trail tied to Git commits
Set Up GitOps with ArgoCD: Git declares desired state; Argo CD reconciles the Kubernetes cluster continuously.

Three properties matter for a working GitOps setup:

  • Declarative: manifests describe the end state, not imperative steps.
  • Versioned: every change is a commit with author, message, and review history.
  • Automated: the controller applies approved changes without manual kubectl for routine releases.

Argo CD adds a fourth practical benefit: visibility. Devs and ops see the same dashboard. That reduces the “works on my laptop” gap during incident response.

How do you install Argo CD on a Kubernetes cluster?

Argo CD runs inside the cluster it manages. You need a working Kubernetes cluster—managed EKS/GKE/AKS, k3s on a VPS, or kind/minikube for learning. Production clusters should already have ingress, TLS, and backup basics covered through your Linux system administration workflow.

Create the namespace and install the manifest

The official install ships as a single consolidated manifest. Pin a stable release tag rather than tracking HEAD.

kubectl create namespace argocd

kubectl apply -n argocd -f \
  https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Wait for pods to become ready:

kubectl get pods -n argocd -w

You should see argocd-server, argocd-repo-server, argocd-application-controller, and Redis-related pods in Running state.

Expose the Argo CD API and UI

For a first login, port-forward is fine. Production should use an Ingress with TLS.

kubectl port-forward svc/argocd-server -n argocd 8080:443

Retrieve the initial admin password:

argocd admin initial-password -n argocd

Log in through the CLI:

argocd login localhost:8080 --username admin --password <INITIAL_PASSWORD> --insecure

Change the password immediately. Store credentials in your team password manager, not in Slack.

Install the Argo CD CLI

The CLI mirrors UI actions and fits CI scripts. On Linux:

curl -sSL -o argocd \
  https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
chmod +x argocd
sudo mv argocd /usr/local/bin/

Official install options are documented at Argo CD Getting Started. Cross-check release notes before upgrading a production instance.

Argo CD Install Pipeline1. Namespaceargocd2. Apply YAMLinstall.yaml3. IngressTLS + DNS4. CLI loginRotate pwdPost-install checklistRBAC policies · repo credentials · AppProject limitsNetworkPolicy · SSO · backup of argocd namespaceMonitor with Prometheus Alertmanager
Install Argo CD in four steps, then harden RBAC, repo access, and monitoring before production traffic.

How do you structure a Git repository for Argo CD Applications?

Repo layout determines how cleanly you scale from one app to twenty. A pattern I recommend for small and mid-size teams:

gitops-repo/
├── apps/
│   ├── staging/
│   │   └── web-app/
│   │       └── application.yaml
│   └── production/
│       └── web-app/
│           └── application.yaml
├── manifests/
│   ├── base/
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   └── kustomization.yaml
│   └── overlays/
│       ├── staging/
│       │   └── kustomization.yaml
│       └── production/
│           └── kustomization.yaml
└── projects/
    └── team-platform.yaml

Kustomize keeps DRY bases with environment-specific patches. Helm works when charts already exist upstream. Plain YAML is fine for two-service prototypes—just split early before copy-paste spreads.

Keep application source code in a separate repo from cluster manifests. That separation lets ops approve infra changes without blocking feature development. CI builds the container image; GitOps repo pins the new image tag.

Validate manifests locally before pushing. A JSON formatter helps when debugging ConfigMaps or Helm output pasted into tickets. For larger teams, add kubeconform or kyverno policy checks in CI on every pull request.

How do you define and register an Argo CD Application?

An Application CRD binds a Git path to a destination cluster and namespace. Here is a minimal example using Kustomize:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web-app-staging
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/gitops-repo.git
    targetRevision: main
    path: manifests/overlays/staging
  destination:
    server: https://kubernetes.default.svc
    namespace: web-staging
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Apply it:

kubectl apply -f apps/staging/web-app/application.yaml

Or use the CLI:

argocd app create web-app-staging \
  --repo https://github.com/your-org/gitops-repo.git \
  --path manifests/overlays/staging \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace web-staging \
  --sync-policy automated \
  --auto-prune \
  --self-heal

Watch sync status:

argocd app get web-app-staging
argocd app sync web-app-staging

The UI shows green health when Deployments, Services, and Ingress objects match Git. Yellow or red usually means a render error, a missing secret, or an image pull failure—check the events panel first.

AppProject boundaries

Replace the wide-open default project in production. An AppProject whitelists repos, destination clusters, and resource kinds:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: platform
  namespace: argocd
spec:
  sourceRepos:
    - https://github.com/your-org/gitops-repo.git
  destinations:
    - namespace: web-*
      server: https://kubernetes.default.svc
  clusterResourceWhitelist:
    - group: ""
      kind: Namespace

This stops a misconfigured Application from deploying cluster-scoped resources to the wrong namespace.

Application CRD MappingsourcerepoURL + pathtargetRevisionApplicationname + projectsyncPolicydestinationserver + namespacesyncPolicy.automatedprune: true — remove orphans from clusterselfHeal: true — revert manual kubectl editsCreateNamespace=true — auto-provision target NS
An Argo CD Application links a Git path to a cluster namespace and defines how sync behaves.

How do sync policies and promotion workflows work in Argo CD GitOps?

Automated sync with prune and self-heal is the default goal for non-production and often for production too. Prune deletes cluster objects removed from Git. Self-heal undoes manual hotfixes that bypass Git—valuable for auditability, frustrating if someone expects kubectl patches to stick.

Many teams use manual sync in production until confidence is high. Add an approval step in CI that merges a tag bump only after staging passes smoke tests. That mirrors how I structure staging environments that mirror production on traditional stacks.

Promotion flow in practice:

  1. Developer merges app code; CI builds and pushes myapp:1.4.2.
  2. Bot or engineer opens a PR updating the image tag in manifests/overlays/staging.
  3. Argo CD syncs staging automatically; QA validates.
  4. A second PR promotes the same tag to manifests/overlays/production.
  5. Production sync runs—manual or automated based on policy.

Compare tooling choices before you commit org-wide. This table summarises common patterns:

ApproachSource of truthDrift handlingBest fit
Manual kubectlWhoever ran the commandNone—cluster diverges silentlyLocal experiments only
CI push deployCI script + artifactPartial—depends on script idempotencyVM/bare-metal, Laravel + Deployer
Argo CD GitOpsGit repoSelf-heal + diff UIKubernetes-native teams
Flux CDGit repoController reconciliationGit-native, multi-tenant clusters

For a deeper tool comparison, read Flux CD vs Argo CD compared and Argo CD GitOps for Kubernetes. Argo CD wins when you want a strong UI and application-centric model; Flux fits teams that prefer everything as plain Git without a dashboard dependency.

How do you secure Argo CD for production GitOps?

An exposed Argo CD instance is a remote admin panel for your cluster. Treat it like production infrastructure from day one.

Authentication and RBAC

Enable SSO through OIDC—GitLab, GitHub, Google, or Okta. Map groups to Argo CD roles. Replace shared admin credentials.

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  policy.csv: |
    g, platform-admins, role:admin
    g, dev-team, role:developer
    p, role:developer, applications, sync, */*, allow

Repository credentials

Private Git repos need credentials stored as Kubernetes secrets. Argo CD supports HTTPS tokens and SSH deploy keys. Prefer a read-only deploy key scoped to the GitOps repo only.

argocd repo add https://github.com/your-org/gitops-repo.git \
  --username git \
  --password <GITHUB_PAT>

Never commit tokens into the GitOps repo itself—that defeats the purpose.

Secrets in manifests

Do not store plaintext database passwords in Git. Use External Secrets Operator, Sealed Secrets, or SOPS-encrypted files. Argo CD syncs the wrapper; the cluster resolves the secret at runtime. On legal-tech and client portals I have shipped, document-handling systems demand the same discipline—secrets live outside VCS.

Network and multi-cluster

Restrict ingress to VPN or zero-trust proxy. For multiple clusters, register each with argocd cluster add and scope AppProjects per environment. Patterns for that are covered in multi-cluster GitOps patterns.

Wire alerts when sync fails or apps stay degraded. Pair Argo CD metrics with Prometheus Alertmanager so on-call hears about drift before users do. Ongoing hardening fits under support and maintenance if your team lacks dedicated platform engineers.

Production Hardening LayersIngress + TLS + IP allowlistSSO (OIDC) + RBAC policy.csvAppProject repo + destination limitsSealed Secrets / External Secrets — no plain creds in GitAudit logs + Prometheus alerts on sync failure
Layer SSO, RBAC, AppProjects, secret operators, and alerting when you Set Up GitOps with ArgoCD for production.

What are common mistakes when you Set Up GitOps with ArgoCD?

Most failures I see are operational, not Argo-specific.

  • Sync loops: an annotation or label churns every reconcile because a mutating webhook rewrites fields. Fix the webhook or ignore diffs with ignoreDifferences.
  • Prune accidents: automated prune deletes a PVC or Ingress someone added manually but never committed. Train the team: if it is not in Git, it does not exist.
  • Helm version skew: local helm template uses a different chart version than Argo CD’s embedded Helm. Pin chart versions in Application spec.
  • Resource hooks blocking sync: PreSync Jobs that never complete leave apps stuck Progressing. Set sensible timeouts.
  • Ignoring health checks: Deployment reports Synced but pods crash loop because probes fail. Watch pod events, not only Argo status.

The Kubernetes documentation on declarative configuration explains why idempotent manifests matter. GitOps amplifies that discipline—bad YAML deploys faster, but also rolls back faster.

On sister sites I maintain with Deployer and GitLab CI, releases are symlink swaps on Ubuntu. Kubernetes adds moving parts—CRDs, operators, HPA—but the GitOps mindset is identical: one approved change set, one automated apply, one audit trail. Sites like Notary Kathmandu and Adventure Third Pole Trek benefit from that predictability even when the runtime differs.

If you are migrating from shell-based deploys, treat GitOps adoption as incremental. Containerise one service, add one Application, prove rollback, then expand. Testing and optimization practices still apply—GitOps does not replace smoke tests.

Key Takeaways

  • Install Argo CD into an argocd namespace, expose the UI with TLS, and rotate the default admin password on first login.
  • Split app code repos from GitOps manifest repos; use Kustomize or Helm overlays per environment.
  • Define Applications with explicit sync policy—enable prune and self-heal only when the team accepts that Git wins over manual kubectl.
  • Replace the default AppProject with scoped projects, SSO, and read-only repo credentials before production traffic.
  • Never store raw secrets in Git; use Sealed Secrets, SOPS, or External Secrets Operator.
  • Monitor sync health and wire alerts; read declarative Kubernetes deployments with GitOps for adjacent patterns.

People Also Ask

Do you need Helm to use Argo CD?

No. Argo CD supports plain YAML directories, Kustomize, Jsonnet, and Helm. Pick the tool your team already maintains. Kustomize overlays are enough for many Laravel API plus worker deployments on Kubernetes.

Can Argo CD deploy to multiple clusters?

Yes. Register each cluster with the Argo CD CLI or a cluster secret. Point different Applications at the same Git path with different destination servers, or use overlay paths per cluster.

How is Argo CD different from Jenkins or GitLab CI for deploys?

CI builds artifacts and may trigger deploys. Argo CD continuously reconciles cluster state to Git. CI is event-driven on push; Argo CD is level-driven—it corrects drift until Git and cluster match.

Is Argo CD safe for production?

Yes, with SSO, RBAC, AppProjects, secret operators, and monitored sync policies. Thousands of organisations run it in production. Your safety comes from process and config, not from skipping GitOps.

Ship declarative Kubernetes with confidence

You now have a complete path to Set Up GitOps with ArgoCD: install the controller, structure your repo, register Applications, tune sync policy, and lock down access. Start on staging, prove promotion and rollback, then extend to production clusters. If you want help designing GitOps around your Laravel, WordPress, or custom app stack—or migrating from Deployer-based releases—contact us or browse the portfolio for shipped examples. More background lives on the blog, including infrastructure vs application GitOps and the home page service overview.

Frequently Asked Questions

GitOps means every desired cluster state lives in version control, and a controller reconciles live resources against that declared state. Push a commit and the platform applies it; drift gets corrected or flagged, and rollback is a git revert. Argo CD is a CNCF-graduated continuous delivery tool built for Kubernetes. It reads Helm charts, Kustomize overlays, plain YAML, or Jsonnet, renders manifests, compares them to live objects, and syncs when allowed. The UI shows diffs, health, and history—useful when a small team owns both application code and cluster operations.

Argo CD runs inside the cluster it manages. Create the argocd namespace and apply the official consolidated manifest, pinning a stable release tag rather than tracking HEAD. Wait until argocd-server, argocd-repo-server, argocd-application-controller, and Redis-related pods reach Running state. For first login, port-forward argocd-server; production should use Ingress with TLS. Retrieve the initial admin password with argocd admin initial-password, log in via CLI or UI, and change that password immediately. Install the argocd CLI on Linux from the official GitHub release binary for CI scripts and day-to-day operations.

No. Argo CD supports plain YAML directories, Kustomize, Jsonnet, and Helm. Pick the tool your team already maintains.

A scalable layout separates apps per environment, shared manifests, and project boundaries. Place Application CRDs under apps/staging and apps/production, keep reusable bases under manifests/base, and environment patches under manifests/overlays. Store AppProject definitions under projects/. Keep application source code in a separate repo from cluster manifests so ops can approve infra changes without blocking feature work. CI builds the container image; the GitOps repo pins the new tag. Validate manifests locally before pushing, and for larger teams add kubeconform or Kyverno policy checks on every pull request.

An Application CRD binds a Git path to a destination cluster and namespace. Set spec.source with repoURL, targetRevision, and path—for example manifests/overlays/staging. Set spec.destination with server and namespace. Enable syncPolicy.automated with prune and selfHeal when Git should win over manual changes, and add syncOptions like CreateNamespace=true. Apply the YAML with kubectl or create the app via argocd app create with matching flags. Watch status with argocd app get; yellow or red usually means a render error, missing secret, or image pull failure—check the events panel first.

An AppProject whitelists which repositories, destination clusters, and resource kinds an Application may use. The default project is wide open. In production, define scoped projects—for example platform—that list allowed sourceRepos, restrict destinations to namespaces like web-* on the local cluster, and set clusterResourceWhitelist entries such as Namespace only where needed. This stops a misconfigured Application from deploying cluster-scoped resources to the wrong namespace or pulling manifests from an unapproved repo. Treat AppProject boundaries as part of your production hardening, alongside SSO and RBAC.

Automated sync applies Git changes without manual kubectl for routine releases. Prune deletes cluster objects removed from Git—powerful for cleanliness, dangerous if someone added resources manually and never committed them. Self-heal undoes manual hotfixes that bypass Git, restoring auditability but frustrating anyone who expected kubectl patches to stick. Many teams run automated sync with prune and self-heal in non-production first. Production may stay on manual sync until confidence is high, with CI merging tag bumps only after staging smoke tests pass.

A typical flow keeps environments in separate Kustomize or Helm overlays. Developer merges app code; CI builds and pushes a new image tag. A pull request updates that tag in manifests/overlays/staging; Argo CD syncs staging automatically and QA validates. A second PR promotes the same tag to manifests/overlays/production. Production sync runs manual or automated based on policy. This mirrors staging environments that mirror production on traditional stacks—only the runtime differs. Git remains the single approved change set with a full audit trail.

CI builds artifacts and may trigger deploys on push—it is event-driven. Argo CD continuously reconciles cluster state to Git—it is level-driven and corrects drift until Git and the cluster match. On bare-metal or VM stacks, GitLab CI plus Deployer handles symlinked releases well for monoliths. When workloads move to Kubernetes with microservices, sidecars, ingress, and secrets operators, Argo CD closes the gap between what Git declares and what the cluster actually runs. The two complement each other: CI produces images; GitOps pins and applies them.

Both use Git as the source of truth and reconcile cluster state continuously. Argo CD fits teams that want a strong UI and an application-centric model—you see diffs, health, and sync history in one dashboard. Flux fits teams that prefer everything as plain Git without dashboard dependency and works well on multi-tenant clusters. Manual kubectl keeps no drift handling; CI push deploy depends on script idempotency. If you already run Flux, much of the GitOps mental model transfers when you set up Argo CD—the tooling differs, not the discipline.

Yes. Register each cluster with argocd cluster add or a cluster secret, then point Applications at different destination servers or overlay paths per cluster.

Yes, with SSO, RBAC, scoped AppProjects, secret operators, restricted ingress, and monitored sync policies. Thousands of organisations run it in production.

Treat an exposed Argo CD instance as a remote admin panel. Enable SSO through OIDC—GitLab, GitHub, Google, or Okta—and map groups to Argo CD roles via argocd-rbac-cm policy.csv instead of shared admin credentials. Store private repo credentials as Kubernetes secrets with read-only deploy keys scoped to the GitOps repo only; never commit tokens into Git. Restrict ingress to VPN or a zero-trust proxy. For multiple clusters, register each explicitly and scope AppProjects per environment. Wire alerts when sync fails or apps stay degraded, pairing Argo CD metrics with Prometheus Alertmanager.

Do not store plaintext database passwords or API keys in Git—that defeats the purpose of auditable manifests. Use External Secrets Operator, Sealed Secrets, or SOPS-encrypted files instead. Argo CD syncs the wrapper object; the cluster resolves the actual secret at runtime. On client portals and document-handling systems I have shipped, the same rule applies: secrets live outside version control. Pair this with read-only repo credentials so a leaked GitOps repo cannot grant write access back to your source systems.

Sync loops happen when a mutating webhook rewrites fields every reconcile—fix the webhook or use ignoreDifferences. Prune accidents delete PVCs or Ingress objects added manually but never committed; train the team that if it is not in Git, it does not exist. Helm version skew between local helm template and Argo CD’s embedded Helm causes surprise diffs—pin chart versions in the Application spec. PreSync hook Jobs that never complete leave apps stuck Progressing; set sensible timeouts. Finally, Synced status on a Deployment does not mean healthy pods—watch pod events and probe failures, not only Argo’s green indicator.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: