Most CI tools deploy by pushing: the pipeline holds cluster credentials and runs kubectl apply. That works until someone patches a deployment by hand at 2am, and now the cluster and the repository disagree with nobody the wiser.

Argo CD inverts it. A controller runs inside the cluster, watches a Git repository, and continuously reconciles reality against what’s committed. Git is the desired state; anything else is drift, and drift is either shown to you or silently corrected. That model — GitOps — is now the mainstream way to deploy to Kubernetes: Argo is a CNCF graduated project, and CNCF’s own survey puts it in the majority of respondents’ clusters.

Install

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

# initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret \
  -o jsonpath="{.data.password}" | base64 -d

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

The web UI at https://localhost:8080 is a genuine reason people pick Argo over the alternatives — a live diff between Git and the cluster, per resource, with the sync button next to it.

Your first Application

An Application says: this Git path, into this cluster and namespace.

  apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example/my-app-config.git
    targetRevision: main
    path: k8s/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true        # delete resources removed from Git
      selfHeal: true     # revert manual changes to the cluster
    syncOptions:
      - CreateNamespace=true
  

prune and selfHeal are the two switches that decide how strict you are. With both on, kubectl edit in production lasts about ninety seconds — which is the point, and also the thing to warn your team about before you turn it on.

The CLI mirrors the UI:

  argocd app list
argocd app diff my-app        # Git vs cluster, right now
argocd app sync my-app
argocd app history my-app     # and: argocd app rollback my-app <id>
  

The shape that scales

  • Two repositories. Application code in one, Kubernetes manifests in another. CI builds the image and commits a new tag to the config repo; Argo notices and rolls it out. Deploys become a reviewable commit, and rollback is git revert.
  • App of apps. One Application whose Git path contains more Applications, so a whole environment is bootstrapped from a single object.
  • ApplicationSet. Generate Applications from a template — one per cluster, per directory, per team — instead of writing forty near-identical YAML files.
  • Argo Rollouts. A sibling project that swaps the built-in Deployment strategy for canary and blue-green releases with automated analysis.

The two things that trip people up

Secrets do not go in Git as plaintext. GitOps means everything is in the repository, which makes this the first question anyone asks. Use Sealed Secrets, SOPS with age or KMS, or the External Secrets Operator pulling from Vault or a cloud secret manager — what’s committed is an encrypted or referencing object, never the value.

Argo CD is not CI. It doesn’t build, test, or push images. You still need GitHub Actions, GitLab CI, or Jenkins in front of it. The handoff is a commit to the config repository, and that seam is where a deploy pipeline usually needs the most care.

Is it for you?

It needs Kubernetes, and it pays off with more than one environment or cluster. A single container on Railway does not need a reconciliation loop. Three environments, several teams, and an auditor asking who deployed what — that’s where the model earns its keep, because the answer is the Git history.

Next

The other GitOps controller, and when it fits better → Flux

Last updated 23 Aug 2026, 00:00 UTC. history