From Git Chaos to GitOps: Building a Local Development Platform

TL;DR: A 26,657-line YAML file was killing git performance, so I spent the past week building a complete GitOps infrastructure with k3s + ArgoCD + NATS running locally. Perfect for cost-controlled development without API dependencies.

The Problem: When Git Commits Take Forever

It started with a simple git commit that took forever. Investigation revealed the culprit: a massive argocd.yaml file with 26,657 lines making every git operation crawl.

But fixing git performance was just the beginning. The real goal was building an environment for local development that gives me full control over costs and dependencies.

Technology Decisions

Container Orchestration: k3s

Why k3s over full Kubernetes?

  • Lightweight: Perfect for single-node development
  • Resource efficient: Ideal for dedicated hardware
  • Production compatible: Can migrate to full K8s later
  • WSL2 friendly: Works great on Windows dev setups

GitOps: ArgoCD

The heart of the operation with ArgoCD:

  • Git-driven deployments: Push to git, everything updates automatically
  • Declarative: Infrastructure and applications as code
  • GitHub App integration: Secure repository access
  • Visual dashboard: Clear overview of what’s running

Packaging: Helm vs Kustomize

Initially went with Kustomize + Helm hybrid with environment overlays (base/development/production).

Final decision: Pure Helm after realizing we were over-engineering for a single-environment setup:

  • Simpler mental model
  • Better templating for dynamic values
  • Easier to share and reuse charts
  • ArgoCD ApplicationSet handles multiple deployments elegantly

Access Strategy: Cloud vs Local

Explored Cloudflare Tunnel + Zero Trust for external access.

Chose localhost + port-forwarding for development:

  • Portability: Works on any machine that clones the repo
  • Simplicity: No DNS configuration or tunnel setup
  • Tailscale compatible: Remote desktop access gives full GUI experience
  • Cost effective: No external dependencies

Messaging: NATS

For inter-service communication, NATS won because:

  • Sub-millisecond latency
  • JetStream for persistent messaging
  • Tiny resource footprint
  • Simple to configure and maintain

Final Architecture

┌─────────────────────────────────────────────────────────────┐
│                   Development Setup                        │
├─────────────────────────────────────────────────────────────┤
│  Linux Machine (k3s cluster)          Windows (via Tailscale) │
│  ├── ArgoCD (GitOps)                  ├── Remote Desktop    │
│  ├── NATS (Messaging)                 ├── Cursor IDE        │
│  ├── Shared Storage                   └── Browser           │
│  └── Application Platform                                   │
└─────────────────────────────────────────────────────────────┘

Repository Structure

gitops-factory (Infrastructure):

  • k3s installation scripts
  • ArgoCD configuration with GitHub App integration
  • NATS messaging system
  • Shared storage setup
  • Base Helm charts (nginx, shared-storage, application-base)

application-platform (Separate repo):

  • Application orchestration platform
  • Dynamic service spawning/scaling
  • FastAPI management interface

Key Design Decisions

1. Localhost-First Development

Instead of complex DNS/tunnel setups:

# Simple access pattern
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Open https://localhost:8080

Works identically whether you’re:

  • Working directly on the Linux machine
  • Using Tailscale remote desktop access
  • Running on WSL2 on Windows

2. Separate Infrastructure vs Application

  • gitops-factory: Stable infrastructure (ArgoCD, NATS, storage)
  • application-platform: Rapid iteration application code

This separation prevents accidentally breaking the cluster while developing applications.

3. Production-Ready but Simple

Each Helm chart includes:

  • Development values (optimized for k3s)
  • Production values (security contexts, resource limits)
  • The ability to scale from laptop to cloud

What’s Next

  • Complete the application platform implementation
  • Build service templates for different use cases
  • Scale up the hardware for more serious workloads
  • Document everything for the community

Technologies Used

  • k3s: Lightweight Kubernetes distribution
  • ArgoCD: GitOps continuous delivery
  • Helm: Kubernetes package manager
  • NATS: Cloud native messaging system
  • Tailscale: Zero-config VPN for remote access
  • FastAPI: Modern Python web framework
  • GitHub Apps: Secure repository integration

Key Takeaways

  • Start simple, add complexity when needed - We almost over-engineered with Kustomize overlays
  • Local development can be production-ready - Proper Helm charts scale from laptop to cloud
  • Separate concerns cleanly - Infrastructure vs application repositories
  • Choose boring technology - NATS over Kafka, localhost over DNS complexity
  • Cost-effective development is possible - No need for expensive external dependencies

The result? A completely functional GitOps environment for local development with remote access via Tailscale. Git commits are fast again, and we have a solid platform for future projects.


All the technologies mentioned in this post are documented with detailed information and links on the Tools page.