Service 04

Deployment

Local dev that mirrors production. One Helm chart, every environment. ArgoCD GitOps with multi-env values overrides.


The problem

Local docker-compose drifts from prod. 'Works on my k8s' doesn't work.

Most teams use docker-compose locally and Kubernetes in prod. The two diverge immediately: health checks behave differently, secrets are loaded differently, ingress is a different layer entirely. The first time you ship a Kubernetes-specific behavior — service mesh policy, pod disruption budget, init container ordering — you find out locally never tested it.

Teams that do use Kubernetes locally usually use Docker Desktop's embedded cluster — which is slow, resource-heavy, and behaves differently from any managed cloud cluster.


How it works

k3d locally + Helm + ArgoCD GitOps everywhere else — one chart.

Sage uses k3d (k3s in Docker) for local development. k3s is the real Kubernetes distribution used by Rancher and Civo Cloud; it conforms to upstream k8s. Ingress, storage classes, RBAC, network policies — all behave the way they will in production.

The same Helm chart deploys locally and to GKE / EKS / AKS. ArgoCD applications are pre-wired with automated sync, prune, and self-heal. Multi-env values files handle environment-specific overrides. The Dark Factory migration-gated pre-upgrade job ships in the chart by default.

  • k3d for local dev — real Kubernetes (k3s) in Docker; ingress + storage class identical to prod
  • One Helm chart at infra/helm/<product>/ — values.yaml + values-staging.yaml + values-prod.yaml
  • ArgoCD applications pre-wired for staging + prod with automated sync, prune, self-heal
  • Multi-cloud ready — GKE, EKS, AKS, or any conformant Kubernetes (no cloud-specific resources)
  • External Secrets Operator pre-configured for Doppler / Vault / AWS Secrets Manager
  • Database migrations gated by Dark Factory — pre-upgrade Job in the Helm chart
infra/helm/my-product/values.yaml yaml
# infra/helm/my-product/values.yaml — single chart, env-specific overrides
backend:
  image:
    repository: ghcr.io/me/my-product-backend
    pullPolicy: IfNotPresent
  replicas: 2
  resources:
    requests: { cpu: 250m, memory: 512Mi }
    limits:   { cpu: 1000m, memory: 1Gi }

web:
  image:
    repository: ghcr.io/me/my-product-web
  replicas: 2

env:
  CEREBE_API_URL: https://cerebe.momentiq.ai
  OTEL_EXPORTER_OTLP_ENDPOINT: https://tempo.example.com:4317

# infra/argo/my-product.yaml — ArgoCD application
apiVersion: argoproj.io/v1alpha1
kind: Application
spec:
  source:
    helm:
      valueFiles: [values.yaml, values-staging.yaml]
  destination:
    server: https://k8s.staging.example.com
    namespace: my-product
  syncPolicy:
    automated: { prune: true, selfHeal: true }

# Local dev — same Helm chart, k3d cluster
$ make dev
→ k3d cluster created · ingress on :80/:443
→ helm install my-product ./infra/helm/my-product -f values.local.yaml
→ backend ready · web ready · ingress live at https://my-product.localhost

Pricing relevance

Helm + ArgoCD scaffolding is included in every paid tier. Enterprise tier adds VPC-deploy templates, on-prem reference architectures, and SOC2 audit-ready manifests.

Open-source posture

Helm charts, ArgoCD application manifests, and k3d local-dev scripts are OSS (Apache-2.0). The opinionated wiring, observability defaults, and Dark Factory pre-upgrade jobs are documented and free to modify.

Get Started

Local that mirrors prod. One chart everywhere.

k3d for development, the same Helm chart for GKE / EKS / AKS production. No docker-compose drift. No 'works on my k8s' surprises.