ArgoCD: GitOps for Kubernetes Beginners
TOP 5 Jan. 18, 2026, 5:30 a.m.

ArgoCD: GitOps for Kubernetes Beginners

Welcome to the world of GitOps with ArgoCD! If you’re new to Kubernetes and wonder how to keep your clusters in sync with source code, you’ve landed in the right spot. In this guide we’ll walk through the core concepts, set up ArgoCD step‑by‑step, and explore a few real‑world scenarios that showcase its power. By the end, you’ll have a working pipeline that automatically rolls out changes from a Git repository to a live cluster.

What is GitOps?

GitOps is a set of practices that treats Git as the single source of truth for both application code and infrastructure configuration. Every change—be it a new container image tag or a tweak to a Service manifest—is captured in a commit, reviewed, and then automatically applied to the cluster.

This approach brings three immediate benefits: versioned history, auditable changes, and a declarative workflow that removes manual “kubectl apply” steps. Think of GitOps as the “CI/CD” for your cluster’s desired state, not just for your application binaries.

Why Choose ArgoCD?

ArgoCD is a lightweight, Kubernetes‑native continuous delivery engine that implements GitOps out of the box. It watches a Git repository, compares the live state with the desired state, and syncs them automatically or on demand. Unlike traditional CD tools that push changes, ArgoCD pulls—making it a perfect fit for immutable, declarative environments.

Key features that make ArgoCD stand out:

  • Declarative setup: All configuration lives in YAML.
  • Real‑time UI: Visual diff of live vs. desired state.
  • Multi‑cluster support: Manage dozens of clusters from a single instance.
  • Health checks & rollbacks: Built‑in status monitoring and easy revert.

Installing ArgoCD on a Kubernetes Cluster

First, ensure you have a running Kubernetes cluster (Minikube, kind, or a cloud‑hosted cluster) and kubectl configured. The installation itself is a one‑liner using the official manifests.

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

After a few seconds, the ArgoCD components will be up and running. Verify with:

kubectl get pods -n argocd

All pods should show a Running status. If you’re using a local cluster, expose the UI via port‑forwarding:

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

Now open https://localhost:8080 in your browser. The default admin password is the name of the argocd-server pod; retrieve it with:

kubectl -n argocd get pod -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2

Connecting a Git Repository

ArgoCD needs to know where your manifests live. For this tutorial we’ll use a public GitHub repo that contains a simple Nginx deployment. Create an Application resource that points to the repo.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: nginx-demo
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps
    targetRevision: HEAD
    path: helm-guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Apply the manifest:

kubectl apply -f nginx-demo.yaml

ArgoCD will immediately start reconciling the desired state. Visit the UI, click on nginx-demo, and you’ll see a green checkmark indicating that the live cluster matches the Git repo.

Pro tip: Store your ArgoCD Application manifests in a separate “infrastructure” repo. This keeps the separation between application code and delivery configuration clean.

Deploying a Sample Application

Let’s walk through a hands‑on example: deploying a Python Flask app using a Docker image built on every commit. The workflow is:

  1. Push code to Git.
  2. GitHub Actions build and push a Docker image.
  3. ArgoCD detects the updated imageTag in the Helm values file and syncs the change.

First, create a minimal Flask app and a Dockerfile:

# app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello from ArgoCD!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
RUN pip install flask
EXPOSE 5000
CMD ["python", "app.py"]

Next, add a GitHub Actions workflow that builds the image and updates a Helm values file:

name: Build & Deploy Flask

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASS }}

      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKER_USER }}/flask-argo:${{ github.sha }}

      - name: Update Helm values
        run: |
          sed -i "s|imageTag:.*|imageTag: ${{ github.sha }}|g" helm/flask/values.yaml
          git config user.name "github-actions"
          git config user.email "actions@github.com"
          git add helm/flask/values.yaml
          git commit -m "chore: bump image tag to ${{ github.sha }}"
          git push

Notice the sed command that rewrites imageTag. When the workflow pushes the change, ArgoCD sees the new tag, pulls the updated Helm chart, and rolls out the new container without any manual steps.

Sync Strategies: Manual vs. Automated

ArgoCD offers three primary sync modes:

  • Manual: You trigger a sync from the UI or CLI. Ideal for production where you want human approval.
  • Automated (prune & self‑heal): ArgoCD continuously reconciles and removes resources that no longer exist in Git.
  • Hook‑based: Run custom scripts before or after sync, useful for database migrations.

To enable automated sync, add the automated block under syncPolicy (as shown in the earlier Application manifest). For production pipelines, combine automated sync with a SyncWindow that restricts changes to maintenance windows.

Pro tip: Use argocd app wait in your CI pipeline to block further steps until ArgoCD reports a healthy sync. This guarantees that downstream services only see a fully reconciled state.

Health Checks, Rollbacks, and Auditing

ArgoCD evaluates health based on built‑in checks for Deployments, StatefulSets, and custom resources. If a pod crashes, the UI will flag the Application as “Degraded.” You can also define custom health checks using Lua scripts for niche CRDs.

Rollback is as simple as reverting the Git commit that introduced the unwanted change. ArgoCD will detect the revert and automatically roll the cluster back to the previous state.

Every sync operation is logged in the argocd-server audit log, providing a tamper‑proof trail. Pair this with Kubernetes RBAC to restrict who can edit Application manifests, ensuring compliance with security policies.

Real‑World Use Case: Multi‑Team Microservices Platform

Imagine a SaaS platform where each microservice lives in its own Git repo, but all services are deployed into a shared “staging” namespace. Teams push code, CI builds Docker images, and a dedicated “infra” repo contains an ArgoCD Application per service.

Benefits observed by companies adopting this pattern:

  1. Isolation: Each team owns its Application manifest, reducing cross‑team friction.
  2. Speed: Deployments happen in seconds after a merge, enabling rapid feature testing.
  3. Safety: Automated prune removes stale resources, preventing “orphaned” services from consuming resources.

In practice, the infra repo might look like:

# apps/frontend.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: frontend
  namespace: argocd
spec:
  source:
    repoURL: https://github.com/company/frontend
    targetRevision: main
    path: k8s
  destination:
    server: https://kubernetes.default.svc
    namespace: staging
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

When the frontend team updates its Helm values, the change lands in Git, ArgoCD picks it up, and the new version is instantly visible in the staging environment. Production can be promoted by simply changing the targetRevision from staging to release‑v1.2 across all Applications.

Advanced Tips & Best Practices

  • Use Kustomize or Helm: Both are supported natively. Choose Helm for templating, Kustomize for overlay simplicity.
  • Separate Secrets: Store secret manifests in an encrypted store (e.g., SealedSecrets or SOPS) and reference them from the same repo.
  • Limit Scope with Projects: ArgoCD Projects let you sandbox applications, enforce cluster/namespace boundaries, and apply role‑based access.
  • Monitor with Prometheus: ArgoCD exposes metrics at /metrics. Set up alerts for sync failures or health degradations.
Pro tip: Enable resource.exclusions in the ArgoCD ConfigMap to ignore resources that should never be managed by GitOps (e.g., kube‑system components).

CLI Workflow: Managing Applications from the Terminal

While the UI is great for visual diff, the argocd CLI is indispensable for scripting and automation. Install the CLI, then log in:

argocd login localhost:8080 --username admin --password $(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)

List all applications:

argocd app list

Force a sync and wait for health:

argocd app sync nginx-demo --prune --auto-prune
argocd app wait nginx-demo --health

Delete an application cleanly:

argocd app delete nginx-demo --cascade

Scaling ArgoCD for Large Organizations

When managing dozens of clusters, consider the following architectural patterns:

  • ArgoCD Multi‑Cluster Mode: Deploy a single ArgoCD instance that targets multiple clusters via cluster resources.
  • ArgoCD HA: Run three replicas of the server component behind a LoadBalancer for fault tolerance.
  • GitOps Repository Structure: Use a “repo‑per‑environment” strategy (dev, staging, prod) to isolate promotion pipelines.

Performance tuning tips:

  1. Increase controller.concurrentReconciliations to handle more simultaneous syncs.
  2. Set resource.customizations for large CRDs to avoid excessive diff calculations.
  3. Enable dex or an external OIDC provider for single sign‑on across the organization.

Security Considerations

ArgoCD runs with cluster‑admin privileges by default, which is risky in production. Harden the installation by:

  • Creating a dedicated ServiceAccount with limited RBAC rules.
  • Enabling admin.enabled: false in the ConfigMap to disable the built‑in admin user.
  • Using argocd-rbac-csv to define fine‑grained permissions for teams.

Never store plain‑text Docker credentials in the repo. Use Kubernetes Secrets or external secret managers (e.g., HashiCorp Vault) and reference them via imagePullSecrets.

Monitoring & Observability

ArgoCD provides built‑in health dashboards, but integrating with existing observability stacks gives a holistic view. Export metrics to Prometheus and create Grafana dashboards that show:

  • Sync duration per application.
  • Number of out‑of‑sync resources over time.
  • Frequency of rollbacks.

Additionally, forward ArgoCD events to a logging pipeline (e.g., Loki) to trace who triggered a sync and why.

Conclusion

ArgoCD turns Git into the single source of truth for your Kubernetes clusters, delivering fast, reliable, and auditable deployments. By following the steps above—installing ArgoCD, connecting a repo, defining Applications, and leveraging automated sync—you can build a production‑grade GitOps workflow in minutes. Remember to adopt best practices around secret management, RBAC, and observability to keep your pipelines secure and maintainable. Happy deploying, and may your clusters always stay in sync!

Share this article