How to Set Up ArgoCD on Kubernetes — Complete Guide

ArgoCD setup on Kubernetes guide

ArgoCD is the most widely used GitOps tool for Kubernetes. It watches your Git repository and automatically keeps your cluster in sync with whatever you define in code. Push a change to Git — ArgoCD detects it and applies it to the cluster. No manual kubectl apply in production.

This guide covers the complete setup — from installing ArgoCD on your cluster to deploying your first application the GitOps way.


What You’ll Need

  • A running Kubernetes cluster (any cloud provider or local setup)
  • kubectl configured with cluster admin access
  • git installed on your machine
  • A GitHub account (or any Git provider)
  • About 30 minutes

How ArgoCD Works

Before installing, it helps to understand what ArgoCD actually does.

ArgoCD runs inside your Kubernetes cluster as a set of services:

  • API server — handles all requests from the UI and CLI
  • Repo server — clones your Git repositories and processes manifests
  • Application controller — compares what is in Git with what is running in the cluster and reconciles differences
  • Redis — caching layer
  • Dex — optional SSO integration

The flow is simple:

Git repository → ArgoCD repo server → Application controller → Kubernetes cluster

You define the desired state in Git. ArgoCD continuously compares that with the live state. If they differ, ArgoCD syncs the cluster back to what Git says it should be. This also means if someone manually changes something in the cluster with kubectl, ArgoCD will revert it — which is the point.


Step 1 — Install ArgoCD

Create a dedicated namespace and install ArgoCD using the official manifests.

kubectl create namespace argocd

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

Why --server-side and --force-conflicts?

Some ArgoCD CRDs (like ApplicationSet) exceed the 262KB annotation size limit imposed by standard kubectl apply. Server-side apply avoids this by not storing the last-applied-configuration annotation. This is now required for production installs.

Wait for all pods to be ready:

kubectl wait --for=condition=ready pod \
  -l app.kubernetes.io/name=argocd-server \
  -n argocd \
  --timeout=300s

Verify everything is running:

kubectl get pods -n argocd

You should see output similar to:

NAME                                                READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                     1/1     Running   0          2m
argocd-applicationset-controller-xxx                1/1     Running   0          2m
argocd-dex-server-xxx                               1/1     Running   0          2m
argocd-notifications-controller-xxx                 1/1     Running   0          2m
argocd-redis-xxx                                    1/1     Running   0          2m
argocd-repo-server-xxx                              1/1     Running   0          2m
argocd-server-xxx                                   1/1     Running   0          2m


Step 2 — Install the ArgoCD CLI

The CLI is useful for scripting, automation, and managing ArgoCD from the terminal.

macOS:

brew install argocd

Linux (amd64):

curl -sSL -o argocd-linux-amd64 \
  https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64

sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64

Verify installation:

argocd version --client


Step 3 — Access the ArgoCD UI

By default, ArgoCD is not exposed outside the cluster. For local access, use port forwarding.

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

Open https://localhost:8080 in your browser. You will see a certificate warning — this is expected with the default self-signed certificate. Proceed past it.

Get the initial admin password:

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

Log in with:

  • Username: admin
  • Password: output from the command above

⚠️ Important: Change the password immediately after first login. The argocd-initial-admin-secret is auto-deleted after first login in newer ArgoCD versions — save the password before that happens.

Change your password:

argocd login localhost:8080 --insecure
argocd account update-password


Step 4 — Expose ArgoCD for Production (Optional)

Port forwarding is fine for testing. For production, set up an Ingress.

Using NGINX Ingress Controller:

# argocd-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  ingressClassName: nginx
  rules:
  - host: argocd.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              number: 443
  tls:
  - hosts:
    - argocd.yourdomain.com
    secretName: argocd-tls

Apply it:

kubectl apply -f argocd-ingress.yaml

Replace argocd.yourdomain.com with your actual domain. You will need a TLS certificate — use cert-manager with Let’s Encrypt for automatic certificate management.

Alternatively, expose ArgoCD via a LoadBalancer:

kubectl patch svc argocd-server -n argocd \
  -p '{"spec": {"type": "LoadBalancer"}}'


Step 5 — Connect Your Git Repository

Log in to ArgoCD CLI:

argocd login localhost:8080 --insecure

For public repositories: No credentials needed — ArgoCD can clone public repos without authentication.

For private repositories: Add credentials using HTTPS or SSH.

HTTPS (username/password or token):

argocd repo add https://github.com/your-org/your-repo.git \
  --username your-github-username \
  --password your-github-token

SSH:

argocd repo add git@github.com:your-org/your-repo.git \
  --ssh-private-key-path ~/.ssh/id_rsa

Verify the repo is connected:

argocd repo list


Step 6 — Deploy Your First Application

Now the important part — deploying an application the GitOps way.

First, create a simple Kubernetes manifest in your Git repository. Create a file at manifests/deployment.yaml:

# manifests/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

Push this to your Git repository. Then create an ArgoCD Application pointing to it.

Option A — Using the CLI:

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

Option B — Using a YAML manifest (recommended for GitOps):

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

Apply it:

kubectl apply -f argocd-app.yaml

Check the application status:

argocd app get nginx-app

You should see:

Name:               argocd/nginx-app
Project:            default
Server:             https://kubernetes.default.svc
Namespace:          default
URL:                https://localhost:8080/applications/nginx-app
Repo:               https://github.com/your-org/your-repo.git
Target:             main
Path:               manifests
SyncStatus:         Synced to main
HealthStatus:       Healthy

Now open the ArgoCD UI. You will see a visual tree of all deployed resources — the Deployment, the ReplicaSet, the Pods, and the Service — along with their sync and health status.


Step 7 — Test GitOps in Action

This is where it gets interesting. Make a change to your manifest in Git and watch ArgoCD apply it automatically.

Update the replica count in manifests/deployment.yaml:

spec:
  replicas: 3  # Changed from 2 to 3

Commit and push to your repository:

git add manifests/deployment.yaml
git commit -m "Scale nginx to 3 replicas"
git push origin main

ArgoCD polls the repository every 3 minutes by default. Within 3 minutes, it will detect the change and scale your deployment to 3 replicas automatically.

You can also trigger a manual sync immediately:

argocd app sync nginx-app

Watch the rollout:

kubectl get pods -n default -w

You will see a third pod come up. No kubectl apply. No manual intervention. The change went through Git.


Step 8 — Set Up Webhooks for Instant Sync

The default 3-minute polling delay is not ideal for fast deployments. Set up a webhook so ArgoCD syncs immediately when you push to Git.

In your GitHub repository:

  1. Go to SettingsWebhooksAdd webhook
  2. Payload URL: https://argocd.yourdomain.com/api/webhook
  3. Content type: application/json
  4. Events: Select “Just the push event”
  5. Click Add webhook

Now every git push triggers an immediate sync — no waiting for the polling interval.


Step 9 — Install ArgoCD with Helm (Production Method)

For production environments, Helm is the recommended installation method. It gives you more control over configuration.

Add the ArgoCD Helm repository:

helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

Install ArgoCD:

helm install argocd argo/argo-cd \
  --namespace argocd \
  --create-namespace \
  --set server.ingress.enabled=true \
  --set server.ingress.hostname=argocd.yourdomain.com

Check the values file for all available configuration options:

helm show values argo/argo-cd > argocd-values.yaml

Edit argocd-values.yaml to customise your installation, then apply:

helm upgrade argocd argo/argo-cd \
  --namespace argocd \
  -f argocd-values.yaml


Useful ArgoCD Commands

# List all applications
argocd app list

# Get application details
argocd app get nginx-app

# Sync an application manually
argocd app sync nginx-app

# Rollback to a previous version
argocd app rollback nginx-app 1

# Delete an application
argocd app delete nginx-app

# List registered clusters
argocd cluster list

# List connected repositories
argocd repo list

# Check ArgoCD server version
argocd version


Common Issues and Fixes

IssueFix
argocd-initial-admin-secret not foundSecret is auto-deleted after first login. Reset password: argocd admin initial-password -n argocd
Application stuck in OutOfSyncCheck repo credentials: argocd repo list. Check app events: argocd app get <name>
Sync failed with permission errorCheck RBAC — the ArgoCD service account may not have access to the target namespace
Pods not coming up after syncCheck pod events: kubectl describe pod <pod-name> -n <namespace>
Webhook not triggering syncVerify webhook payload URL is correct and ArgoCD server is publicly accessible
Port-forward keeps disconnectingAdd & to run in background or use a proper Ingress for persistent access

Production Checklist

Before running ArgoCD in production, check these:

  • Change the default admin password
  • Set up SSO (Dex with GitHub, Google, or LDAP) instead of using the admin account
  • Enable High Availability installation for the ArgoCD components
  • Set up Ingress with a valid TLS certificate
  • Configure RBAC — give each team access only to their own applications
  • Set up Prometheus metrics scraping for ArgoCD
  • Use pinned versions in Application manifests (targetRevision: v2.3.1 not main) for production apps
  • Enable prune: true and selfHeal: true on all production Applications
  • Back up your ArgoCD configuration — all data is stored in Kubernetes etcd

Next Steps

Now that ArgoCD is running, here is what to explore next:

  • App of Apps pattern — manage multiple applications as a single ArgoCD Application
  • ApplicationSets — deploy the same application across multiple clusters with a template
  • Sync waves — control the order in which resources are applied
  • Sealed Secrets or External Secrets — manage secrets securely in Git
  • Argo Rollouts — progressive delivery with canary and blue-green deployments

You Might Also Like

Leave a Reply