True GitOps at Home: Automating 60+ Apps with ArgoCD, Keel, and Renovate

|4 min read|

Managing 60+ homelab apps manually is a nightmare. Here's how I built a fully automated, self-healing deployment pipeline using ArgoCD, Keel, and Renovate

Yoga Novaindra

Author

Operating a homelab is fun until you realize you've accumulated over 60 applications across 15+ namespaces, and managing deployments has become a part-time job.

If you are manually running kubectl apply or constantly updating Helm values every time an image gets a new release, you are doing it the hard way. To solve this in my own cluster, I engineered a completely hands-off, self-healing continuous deployment pipeline. This setup proves that GitOps isn't just an enterprise buzzword—it's a necessity for operating a home environment at scale.

By treating a single Git repository as the single source of truth, my infrastructure is entirely declarative, version-controlled, and automated.

Here is a breakdown of how my pipeline handles zero-touch updates and maintenance using ArgoCD, Keel, and Renovate.

Homelab Dashboard

The "App-of-Apps" Pattern with ArgoCD

ArgoCD Dashboard

At the core of my deployment strategy is ArgoCD, specifically leveraging the App-of-Apps pattern. Instead of manually applying manifests for each of my 60+ services, I use a single root application defined in an apps.yml file.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: apps
spec:
  source:
    path: gitops
    repoURL: https://github.com/YogaNovvaindra/kube.git
    targetRevision: HEAD
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

This root application acts as a controller that watches the gitops/ directory in my repository. Whenever a new application definition is committed to this directory, ArgoCD automatically detects the drift, provisions the necessary namespaces, and syncs the child applications.

The selfHeal and prune policies are critical here: they ensure that the live cluster state perfectly mirrors the Git repository. If I (or a rogue process) manually modify a resource directly in the cluster, ArgoCD automatically reverts it back to the state defined in Git.

Zero-Touch Image Updates with Keel

While ArgoCD is phenomenal at handling the state of Kubernetes manifests, managing container image tags manually via Git commits is still tedious. This is where Keel comes in.

Keel is a Kubernetes operator designed to automate Helm, DaemonSet, StatefulSet, and Deployment updates. I integrated Keel to continuously monitor my container registries for new image tags.

When a new version of an application is published (for example, a new release of a media server or a monitoring exporter), Keel detects the update and automatically performs a rolling update on the target deployment.

This guarantees that my services are always running the latest tags without requiring me to manually edit a values.yaml file and commit it for every single image bump. It perfectly bridges the gap between static declarative manifests and dynamic release cycles.

Keel Logs

Dependency Maintenance with Renovate

Keel handles immediate image updates in the cluster, but what about the long-term maintainability of the repository itself? That's where Renovate steps in.

Renovate operates at the repository level. It actively scans my Helm charts, Kustomize overlays, and raw manifests for outdated dependencies. When it finds a new semantic version for a chart or a dependency, it automatically opens a Pull Request in my Git repository.

For minor and patch updates, I configure these PRs to be auto-merged. Once merged, ArgoCD detects the commit and immediately syncs the changes to the cluster.

This dual-layered approach is incredibly powerful:

  1. Keel handles rapid, real-time image deployments inside the cluster.
  2. Renovate keeps the underlying declarative code (like Helm chart versions) strictly up-to-date and audited in Git.
Renovate Pull Requests

Why This Architecture Matters

To visualize this entire workflow, here is how a change flows through the system:

This setup isn't just about saving time (though it saves a lot of it). It's about building resilient, enterprise-grade infrastructure at home.

By separating configuration management (ArgoCD) from dynamic artifact updates (Keel) and dependency versioning (Renovate), I have a robust, predictable system. If my entire cluster were to go down today, I wouldn't lose sleep over configurations. The entire state of all 60+ applications could be perfectly restored from a single command:

kubectl apply -f apps.yml

If you're managing a growing homelab and feeling the pain of manual deployments, I highly recommend adopting a similar GitOps approach. It changes everything.


You can check out my full infrastructure repository here: YogaNovvaindra/kube

© 2026 Yoga Novaindra Powered by Ghost