Argo CD

Declarative GitOps continuous delivery for Kubernetes

CI/CD & Build ★ 24.2k stars Hard setup Apache-2.0

Argo CD is a declarative GitOps continuous delivery tool for Kubernetes that keeps cluster state in sync with Git repositories. It provides automated deployment and drift detection.

Key features

  • GitOps deployment model
  • Automated sync and rollback
  • Visual application topology
  • Multi-cluster support

Pros & cons

Strengths

  • Automated drift detection
  • Great web UI
  • Huge community adoption

Trade-offs

  • Kubernetes expertise required
  • Complex at scale

Argo CD replaces

Last reviewed Aug 26, 2026 · 772 words

Argo CD does not build anything, does not run tests, and does not deploy to anything that is not Kubernetes. What it does is watch a Git repository and a cluster, show you the difference, and, if you let it, make the cluster match the repository. If your homelab runs Docker Compose, this guide is not for you and neither is Argo; if you have a k3s or Talos cluster and are still applying manifests with kubectl apply -f from a laptop, it is the tool that turns that into something you can reason about. Apache-2.0, Go, 23,993 stars, rated Hard, 1 GB of RAM minimum for its own components, and the difficulty rating is mostly a rating of Kubernetes.

GitOps changes the direction of the arrow

In a CI-driven pipeline, a job runs kubectl or helm against the cluster, which means the CI system holds cluster credentials and the cluster's real state is whatever the last successful job left. With Argo, nothing pushes: the controller inside the cluster pulls from Git, computes what the live objects should be, and reports "Synced" or "OutOfSync". A manual kubectl edit shows up as drift within minutes; with self-heal enabled it is reverted. Rollback is git revert. The cluster credentials never leave the cluster, and the Git log is the deployment history. That is the whole benefit, and it is large enough that I would not run a cluster without it.

Install is one manifest, then one port-forward

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath='{.data.password}' | base64 -d
kubectl port-forward svc/argocd-server -n argocd 8080:443

That gives you the web UI at https://localhost:8080 as admin. Change the password, delete the initial secret, and, before exposing the UI through an ingress, wire SSO through the bundled Dex to whatever identity provider you run; the admin account is meant for day one. The UI is the best part of the product: a live topology of every Deployment, ReplicaSet, Pod, and Service per application, with diffs, logs, and a sync button, and it is the reason to prefer Argo over its command-line-only rivals for a home cluster you look at occasionally.

Applications, and the app-of-apps pattern

The unit of work is an Application resource: a source (repository, path, revision, and whether it is plain YAML, Kustomize, or a Helm chart) and a destination (cluster, namespace). Ten applications in a homelab is normal. The pattern that keeps it manageable is app-of-apps: one root Application whose path contains the other Application manifests, so adding a service is a Git commit and Argo bootstraps itself from a single kubectl apply. ApplicationSet generates Applications from a list or a directory layout, which is how you get "every folder under apps/ is an app" without writing each one.

Sync policy decides how many surprises you get

syncPolicy:
  automated:
    prune: true
    selfHeal: true
  syncOptions:
    - CreateNamespace=true

prune deletes cluster objects that vanished from Git; selfHeal reverts manual changes. Both are correct for a homelab and both will bite once: a renamed file prunes and recreates a StatefulSet, and self-heal undoes the kubectl scale you did during an incident. Leave automated off for anything holding data until you trust your manifests, and use sync waves and hooks for ordering when a database must exist before its consumer.

What still needs other tools

Argo watches Git, so something else must put the new image tag there: your CI in GitLab CE or Gitea builds the image, pushes it to a registry such as Harbor, and commits the tag bump, or Argo CD Image Updater watches the registry and does the commit for you. Secrets are not Argo's job either; plain Secrets in Git are a mistake, so use Sealed Secrets, SOPS, or an external secrets operator. The CI/CD category lists the build side of the pipeline.

What I'd do

Install it on the k3s cluster with the commands above, put every workload's manifests in one repository with an apps/ directory and an ApplicationSet over it, turn on automated sync with prune and self-heal for stateless services and manual sync for anything with a volume, and add SSO before adding an ingress. Then stop running kubectl apply by hand entirely, because the value of Argo is proportional to how completely Git becomes the only way in.

Similar ci/cd & build apps