ArgoCD: GitOps for Your Homelab Kubernetes
Declarative GitOps continuous delivery. Manage Kubernetes applications through Git with automatic sync.
Overview
ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes that transforms Git repositories into the single source of truth for your infrastructure. Instead of manually running kubectl apply commands, ArgoCD continuously monitors your Git repository and automatically synchronizes the desired state (what’s in Git) with the actual state (what’s running in your cluster).
For homelabbers managing Kubernetes clusters, ArgoCD provides an enterprise-grade workflow that eliminates configuration drift, enables one-click rollbacks, and creates a complete audit trail of all infrastructure changes. Every deployment is tracked in Git history, every change is reviewable through pull requests, and your entire Kubernetes state is version-controlled and reproducible.
What you’ll learn:
- Install and configure ArgoCD on Kubernetes (k0s, K3s, or any distribution)
- Understand GitOps principles and workflow
- Deploy applications from Git repositories
- Configure sync policies (automatic vs. manual)
- Manage multi-environment deployments (dev, staging, production)
- Implement Helm chart deployments via ArgoCD
- Handle secrets management securely
- Set up multi-cluster management from single ArgoCD instance
- Troubleshoot common ArgoCD sync issues
Why ArgoCD?
Instead of SSHing into servers and running deployment commands (imperative), you push changes to Git, and ArgoCD ensures your cluster matches (declarative). This paradigm shift brings:
- Single source of truth: Git is the authority
- Audit trail: Every change is a Git commit
- Easy rollback: Revert Git commit to rollback deployment
- Disaster recovery: Recreate entire cluster from Git
- Team collaboration: Code review for infrastructure changes
Prerequisites
Before starting, ensure you have:
- Running Kubernetes cluster (k0s, K3s, K8s, or any CNCF-conformant)
- Minimum 2 GB RAM available
- Minimum 2 CPU cores available
- Cluster admin access (for ArgoCD installation)
- kubectl configured to access your cluster
- Git repository (GitHub, GitLab, Gitea, or any Git server)
- Public or private repository access
- SSH keys or personal access tokens for private repos
- Basic Kubernetes knowledge:
- Deployments, Services, ConfigMaps
- Namespaces and RBAC
- Helm charts (helpful but not required)
- Understanding of Git:
- Commits, branches, pull requests
- Repository management
Recommended cluster:
- k0s or K3s single-node or multi-node cluster
- Ingress controller installed (nginx-ingress, Traefik)
- Storage provisioner configured (OpenEBS, local-path)
If you don’t have a cluster yet, follow our k0s guide or K3s guide first.
Understanding GitOps and ArgoCD
What is GitOps?
GitOps is a paradigm where:
- Git is the source of truth: All infrastructure configuration lives in Git
- Declarative state: You declare “what you want,” not “how to get there”
- Automated convergence: Tools (like ArgoCD) ensure reality matches Git
- Pull-based deployment: Cluster pulls changes, not pushed from CI/CD
Traditional deployment:
Developer → CI/CD Pipeline → kubectl apply → Kubernetes
(push-based) GitOps deployment:
Developer → Git Repository ← ArgoCD → Kubernetes
(pull-based) (monitors & syncs) Core GitOps Principles
- Declarative: Entire system described declaratively
- Versioned: Canonical state version-controlled in Git
- Immutable: Desired state stored in immutable commits
- Pulled automatically: Software agents pull desired state from Git
- Continuously reconciled: Agents ensure reality matches desired state
ArgoCD Architecture
┌─────────────────────────────────────────────────────┐
│ Git Repository │
│ (Single Source of Truth) │
│ ├── app-1/ │
│ │ └── deployment.yaml │
│ ├── app-2/ │
│ │ └── helm-chart/ │
│ └── app-3/ │
│ └── kustomize/ │
└────────────────┬────────────────────────────────────┘
│
│ (monitors for changes)
↓
┌─────────────────────────────────────────────────────┐
│ ArgoCD Components │
│ ├── API Server (Web UI + API) │
│ ├── Repository Server (Git interaction) │
│ ├── Application Controller (Sync logic) │
│ └── Redis (Cache) │
└────────────────┬────────────────────────────────────┘
│
│ (applies changes via kubectl)
↓
┌─────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ ├── Namespace: app-1 │
│ ├── Namespace: app-2 │
│ └── Namespace: app-3 │
└─────────────────────────────────────────────────────┘ Components:
- API Server: Exposes Web UI and API, handles authentication
- Repository Server: Clones and caches Git repositories
- Application Controller: Monitors applications, compares Git vs. cluster state
- Redis: Caches repository data for performance
Installation and Initial Setup
Method 1: Official Installation (Recommended)
Step 1: Create ArgoCD namespace
# Create namespace
kubectl create namespace argocd
# Verify
kubectl get namespace argocd Step 2: Install ArgoCD
# Install ArgoCD
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Wait for pods to be ready (may take 2-3 minutes)
kubectl wait --for=condition=ready pod --all -n argocd --timeout=300s
# Verify installation
kubectl get pods -n argocd
# Expected output:
# NAME READY STATUS RESTARTS AGE
# argocd-application-controller-0 1/1 Running 0 2m
# argocd-dex-server-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 3: Access ArgoCD UI
Option A: Port Forward (Quick Access)
# Forward ArgoCD server port to localhost
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Access UI at: https://localhost:8080
# (Accept self-signed certificate warning) Option B: Ingress (Production Access)
# argocd-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server
namespace: argocd
annotations:
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
ingressClassName: nginx
rules:
- host: argocd.homelab.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 443
tls:
- hosts:
- argocd.homelab.local
secretName: argocd-server-tls # Apply ingress
kubectl apply -f argocd-ingress.yaml
# Add to /etc/hosts
echo "192.168.1.10 argocd.homelab.local" | sudo tee -a /etc/hosts
# Access at: https://argocd.homelab.local Step 4: Get initial admin password
# Retrieve initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
# Output: random-generated-password
# Login to ArgoCD:
# Username: admin
# Password: <output-from-above-command> Step 5: Change admin password (recommended)
# Install ArgoCD CLI
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
# Login via CLI
argocd login localhost:8080 --username admin --password <initial-password> --insecure
# Update password
argocd account update-password
# Delete initial secret (optional, for security)
kubectl -n argocd delete secret argocd-initial-admin-secret Creating Your First GitOps Repository
Repository Structure
Create a Git repository with this structure:
homelab-gitops/
├── apps/
│ ├── nginx/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── ingress.yaml
│ ├── postgres/
│ │ └── statefulset.yaml
│ └── wordpress/
│ └── helm-chart/
├── infrastructure/
│ ├── namespaces/
│ │ └── namespaces.yaml
│ └── ingress-nginx/
│ └── values.yaml
└── README.md Example Application: Nginx
Create apps/nginx/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m" Create apps/nginx/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP Create apps/nginx/ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx
namespace: default
spec:
ingressClassName: nginx
rules:
- host: nginx.homelab.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80 Push to Git:
cd homelab-gitops
git init
git add .
git commit -m "Add nginx application"
git remote add origin https://github.com/yourusername/homelab-gitops.git
git push -u origin main Deploying Applications with ArgoCD
Method 1: Web UI
Step 1: Create new application
- Login to ArgoCD UI
- Click ”+ New App” button
- Fill in application details:
General:
- Application Name:
nginx - Project:
default - Sync Policy:
Manual(change to automatic later)
Source:
- Repository URL:
https://github.com/yourusername/homelab-gitops - Revision:
HEAD(or specific branch/tag) - Path:
apps/nginx
Destination:
- Cluster URL:
https://kubernetes.default.svc(in-cluster) - Namespace:
default
- Click “Create”
Step 2: Sync application
- Click on the
nginxapplication - Click “Sync” button
- Review changes
- Click “Synchronize”
ArgoCD will apply all YAML files in apps/nginx/ to your cluster.
Step 3: Verify deployment
# Check pods
kubectl get pods -l app=nginx
# Check service
kubectl get svc nginx
# Check ingress
kubectl get ingress nginx
# Test application
curl http://nginx.homelab.local Method 2: ArgoCD CLI
# Create application via CLI
argocd app create nginx --repo https://github.com/yourusername/homelab-gitops --path apps/nginx --dest-server https://kubernetes.default.svc --dest-namespace default --sync-policy manual
# List applications
argocd app list
# Get application details
argocd app get nginx
# Sync application
argocd app sync nginx
# Watch sync progress
argocd app wait nginx --health Method 3: Declarative (GitOps for ArgoCD itself!)
Create argocd-apps/nginx-app.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: HEAD
path: apps/nginx
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true # Apply ArgoCD application
kubectl apply -f argocd-apps/nginx-app.yaml
# ArgoCD will automatically sync Sync Policies and Automation
Manual Sync vs. Automatic Sync
Manual Sync:
- Changes in Git don’t automatically deploy
- Requires manual “Sync” button click or CLI command
- Good for: Production environments, critical applications
Automatic Sync:
- ArgoCD polls Git (default: every 3 minutes)
- Automatically syncs when changes detected
- Good for: Development environments, infrastructure
Configuring Automatic Sync
Via Web UI:
- Click application → App Details
- Click “Edit”
- Under Sync Policy, select “Automatic”
- Enable options:
- Prune Resources: Delete resources removed from Git
- Self Heal: Revert manual changes to Git state
Via YAML:
spec:
syncPolicy:
automated:
prune: true # Delete resources not in Git
selfHeal: true # Revert manual kubectl changes
syncOptions:
- CreateNamespace=true # Auto-create namespace if missing Via CLI:
# Enable automatic sync
argocd app set nginx --sync-policy automated
# Enable pruning
argocd app set nginx --auto-prune
# Enable self-healing
argocd app set nginx --self-heal Sync Windows (Scheduled Deployments)
Restrict syncing to specific time windows:
spec:
syncPolicy:
syncOptions:
- CreateNamespace=true
automated:
prune: true
selfHeal: true
# Only sync during maintenance windows
syncWindows:
- kind: allow
schedule: '0 2 * * *' # Daily at 2 AM
duration: 1h
applications:
- nginx Working with Helm Charts
ArgoCD natively supports Helm charts without requiring Helm CLI.
Deploying Helm Chart from Git
Repository structure:
homelab-gitops/
└── apps/
└── wordpress/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
└── service.yaml ArgoCD Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: wordpress
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: HEAD
path: apps/wordpress
helm:
valueFiles:
- values.yaml
parameters:
- name: replicaCount
value: "2"
destination:
server: https://kubernetes.default.svc
namespace: wordpress
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true Deploying from Helm Repository
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: grafana
namespace: argocd
spec:
project: default
source:
chart: grafana
repoURL: https://grafana.github.io/helm-charts
targetRevision: 6.50.0
helm:
values: |
adminPassword: admin
persistence:
enabled: true
size: 5Gi
ingress:
enabled: true
hosts:
- grafana.homelab.local
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true kubectl apply -f grafana-app.yaml Managing Secrets with ArgoCD
Problem: Secrets in Git
Never commit secrets in plain text to Git!
# BAD - Secret exposed in Git
apiVersion: v1
kind: Secret
metadata:
name: db-password
data:
password: bXlzZWNyZXRwYXNzd29yZA== # base64 is NOT encryption! Solution 1: Sealed Secrets
Install Sealed Secrets controller:
# Install Sealed Secrets
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# Install kubeseal CLI
curl -L https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/kubeseal-0.24.0-linux-amd64.tar.gz | tar xz
sudo install -m 755 kubeseal /usr/local/bin/kubeseal Create sealed secret:
# Create regular secret (not applied)
kubectl create secret generic db-password --from-literal=password=supersecret --dry-run=client -o yaml > secret.yaml
# Seal the secret
kubeseal -f secret.yaml -w sealed-secret.yaml
# Now sealed-secret.yaml can be committed to Git
cat sealed-secret.yaml # sealed-secret.yaml (safe to commit)
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: db-password
spec:
encryptedData:
password: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq... # Encrypted Commit to Git:
git add sealed-secret.yaml
git commit -m "Add sealed database password"
git push ArgoCD syncs the SealedSecret, and the controller decrypts it into a regular Secret.
Solution 2: External Secrets Operator
Install External Secrets Operator:
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets -n external-secrets-system --create-namespace Configure secret store (e.g., Vault, AWS Secrets Manager):
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
spec:
provider:
vault:
server: "http://vault.default.svc.cluster.local:8200"
path: "secret"
version: "v2"
auth:
kubernetes:
mountPath: "kubernetes"
role: "argocd" Reference external secret:
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-password
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: db-password
data:
- secretKey: password
remoteRef:
key: database/postgres
property: password Solution 3: Git-Crypt (Simple Encryption)
# Install git-crypt
sudo apt install git-crypt
# Initialize encryption in repo
cd homelab-gitops
git-crypt init
# Add secret files to .gitattributes
echo "secrets/*.yaml filter=git-crypt diff=git-crypt" >> .gitattributes
# Now secrets/*.yaml files are encrypted in Git Multi-Environment Management
Directory Structure for Environments
homelab-gitops/
├── base/
│ └── nginx/
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/
├── dev/
│ ├── kustomization.yaml
│ └── patch-replicas.yaml
├── staging/
│ ├── kustomization.yaml
│ └── patch-replicas.yaml
└── production/
├── kustomization.yaml
├── patch-replicas.yaml
└── patch-resources.yaml base/nginx/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml overlays/production/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base/nginx
patches:
- patch-replicas.yaml
- patch-resources.yaml
namespace: production overlays/production/patch-replicas.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 5 # Production uses 5 replicas ArgoCD Applications (one per environment):
# production-nginx.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-production
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: main
path: overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true # dev-nginx.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-dev
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: develop # Different branch
path: overlays/dev
destination:
server: https://kubernetes.default.svc
namespace: dev
syncPolicy:
automated:
prune: true
selfHeal: true Multi-Cluster Management
Adding External Cluster
Step 1: Get external cluster credentials
# List clusters in kubeconfig
kubectl config get-contexts
# Add cluster to ArgoCD
argocd cluster add k3s-cluster --name production-cluster
# List registered clusters
argocd cluster list Step 2: Deploy to external cluster
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx-remote
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: HEAD
path: apps/nginx
destination:
name: production-cluster # External cluster
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true App of Apps Pattern
Manage multiple applications with one application:
Create apps/applications.yaml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nginx
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: HEAD
path: apps/nginx
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: postgres
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: HEAD
path: apps/postgres
destination:
server: https://kubernetes.default.svc
namespace: databases
syncPolicy:
automated:
prune: true
selfHeal: true Create root app:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/yourusername/homelab-gitops
targetRevision: HEAD
path: apps
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true Now managing root-app manages all child applications!
Troubleshooting Common Issues
Issue: Application Stuck in “Progressing”
# Get application status
argocd app get <app-name>
# Check sync operation details
argocd app get <app-name> --show-operation
# Describe application in Kubernetes
kubectl describe application <app-name> -n argocd
# Common causes:
# 1. Resource quota exceeded
# 2. Image pull errors
# 3. Invalid YAML syntax Issue: “OutOfSync” Status
Symptom: Application shows OutOfSync even after sync
Solutions:
# 1. Check for manual changes
kubectl get deployment nginx -o yaml
# 2. Force hard refresh
argocd app get <app-name> --hard-refresh
# 3. Ignore specific fields
# Add to Application spec:
spec:
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas # Ignore replica count differences Issue: Git Repository Connection Failed
# Test repository connectivity
argocd repo add https://github.com/yourusername/homelab-gitops
# For private repositories, add SSH key or token
argocd repo add [email protected]:yourusername/homelab-gitops.git --ssh-private-key-path ~/.ssh/id_rsa
# Or use HTTPS with token
argocd repo add https://github.com/yourusername/homelab-gitops.git --username yourusername --password ghp_yourtoken Issue: Sync Loops (Continuous Resyncing)
Symptom: Application syncs repeatedly without settling
Solutions:
# Add ignoreDifferences for auto-generated fields
spec:
ignoreDifferences:
- group: "*"
kind: "*"
jsonPointers:
- /metadata/annotations/deployment.kubernetes.io~1revision
- /metadata/managedFields Issue: Permission Denied
# Check ArgoCD RBAC
kubectl get clusterrole argocd-server -o yaml
# Grant additional permissions
kubectl edit clusterrolebinding argocd-application-controller Best Practices for Homelab GitOps
1. Separate Git Repositories
├── homelab-apps/ # Application manifests
├── homelab-infrastructure/ # Infrastructure (ingress, storage)
└── homelab-argocd/ # ArgoCD applications (app of apps) 2. Use Environments with Branches/Directories
Option A: Branch per environment
main→ productionstaging→ stagingdevelop→ development
Option B: Directory per environment (recommended)
overlays/
├── dev/
├── staging/
└── production/ 3. Enable Notifications
# Install ArgoCD notifications
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/stable/manifests/install.yaml
# Configure Slack webhook
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
data:
service.slack: |
token: xoxb-your-slack-token
template.app-deployed: |
message: Application {{.app.metadata.name}} deployed to {{.app.spec.destination.namespace}}
trigger.on-deployed: |
- when: app.status.operationState.phase in ['Succeeded']
send: [app-deployed] 4. Implement Progressive Delivery
Use Argo Rollouts for canary deployments:
kubectl create namespace argo-rollouts
kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: nginx-rollout
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 20
- pause: {duration: 1m}
- setWeight: 40
- pause: {duration: 1m}
- setWeight: 60
- pause: {duration: 1m}
- setWeight: 80
- pause: {duration: 1m}
template:
spec:
containers:
- name: nginx
image: nginx:1.25 5. Regular Backups
# Backup ArgoCD configuration
kubectl get applications -n argocd -o yaml > argocd-apps-backup.yaml
kubectl get appprojects -n argocd -o yaml > argocd-projects-backup.yaml
# Since everything is in Git, cluster rebuild is:
# 1. Deploy ArgoCD
# 2. Apply root application
# 3. Wait for sync Conclusion and Next Steps
ArgoCD brings enterprise-grade GitOps to your homelab, transforming Git into the single source of truth for your Kubernetes infrastructure. By automating synchronization between Git and your cluster, ArgoCD eliminates configuration drift, enables instant rollbacks, and creates a complete audit trail of all changes.
Key Takeaways
- GitOps paradigm: Git is the source of truth
- Declarative: Describe desired state, not imperative steps
- Automated sync: Pull-based deployment from Git
- Multi-environment: Manage dev, staging, production from one repo
- Multi-cluster: Control multiple clusters from single ArgoCD
- Helm support: Native Helm chart deployment
- Audit trail: Every change tracked in Git history
When to Use ArgoCD
Perfect for:
- Kubernetes-based homelabs (k0s, K3s, K8s)
- Teams managing multiple environments
- Infrastructure-as-code workflows
- Compliance and audit requirements
- Multi-cluster management
- Advanced deployment strategies (canary, blue-green)
Consider alternatives if:
- Not using Kubernetes (use Ansible, Docker Compose)
- Single-container deployments (use Portainer, Dockge)
- Maximum simplicity preferred (kubectl apply works fine)
Recommended Workflow
- Set up Git repository with organized structure
- Install ArgoCD on Kubernetes cluster
- Create first application (manual sync)
- Test sync process with small changes
- Enable automatic sync for non-critical apps
- Implement secrets management (Sealed Secrets)
- Add notifications (Slack, Discord, email)
- Expand to multi-environment (dev, staging, prod)
Next Steps
Beginner:
- Install ArgoCD on k0s/K3s cluster
- Create Git repository with sample app
- Deploy application via ArgoCD UI
- Make change in Git, observe auto-sync
Intermediate:
- Set up multi-environment with Kustomize
- Implement Sealed Secrets
- Configure automatic sync with self-heal
- Deploy Helm charts via ArgoCD
Advanced:
- Implement app-of-apps pattern
- Set up multi-cluster management
- Configure Argo Rollouts (progressive delivery)
- Integrate with CI/CD pipeline
- Implement RBAC and SSO
Related Guides
- k0s Guide - Zero-friction Kubernetes for homelabs
- K3s Guide - Lightweight Kubernetes alternative
- Dockge Guide - Docker Compose management (pre-Kubernetes)
- Portainer Guide - Container management GUI
Resources
- Official Documentation: https://argo-cd.readthedocs.io/
- GitHub Repository: https://github.com/argoproj/argo-cd
- GitOps Principles: https://opengitops.dev/
- Argo Rollouts: https://argoproj.github.io/rollouts/
- Community Slack: https://argoproj.github.io/community/join-slack
- Tutorials: https://github.com/argoproj/argocd-example-apps
Document Version: 1.0 Last Updated: December 16, 2024 Based on: ArgoCD v2.9+ Estimated Completion Time: 90 minutes (basic setup), 12-16 hours (production GitOps workflow)
Happy GitOps-ing!