Skip to content

Architecture

dabba is built so the same modules and gitops repo run from a laptop to the cloud. A few ideas make that work.

Provisioning and configuration meet at the kubeconfig

Section titled “Provisioning and configuration meet at the kubeconfig”

Provisioning (kind / k3d / minikube / cloud) and configuring (the platform) are separated by a single interface: a kubeconfig. The provision step outputs one; the configure step takes only that. So moving to a new substrate changes only the provisioning module — everything above the kubeconfig (Flux, gateway, TLS, secrets, apps) is identical.

dabba up installs an in-cluster Forgejo, seeds it with the gitops content, and points Flux at it. The cluster is self-contained — it carries its own authoritative git, so there’s no external dependency to bootstrap. (Forgejo is pluggable to GitHub or a shared-services hub for larger topologies.)

Per-cluster values (domain, issuer, environment name, generated tokens) live in a cluster-vars ConfigMap that Flux substitutes into the manifests at apply time. The cluster describes its own configuration; the gitops manifests stay generic.

dabba’s relationship to the gitops content is one-way generationdabba.yaml is the source of truth:

  • Hand-authored — the component manifests and Flux Kustomization templates (with ${...} placeholders). dabba never rewrites these.
  • dabba-generated — the thin selection of which components are active, plus the substituted values. These carry a # GENERATED by dabba — do not edit header.

There’s no bidirectional sync to reason about: the real reconciliation is Flux driving actual state toward the config-derived desired state.

dabba ships no credentials. At up, it generates per-environment random secrets, stores the app credentials in OpenBao (delivered to apps by External Secrets), and stashes the one irreducible local secret — the OpenBao root token — in .dabba/<env>/. Retrieve any of them with dabba secret get.

dabba up doesn’t return success after its own steps — it polls until every Flux Kustomization and HelmRelease is Ready and no pod is crashlooping. If something is wrong, it surfaces the actual error from the failing layer (the Flux condition, the pod’s crash reason) instead of a misleading “ready”.

TierWhat
0Local — kind / k3d / minikube, self-contained, self-signed TLS. Available now.
1Cloud — AWS Fargate EKS, real DNS (external-dns) + ACME TLS via Route53, a load-balancer gateway. Available now (substrate: eks).
2Multi-cluster, shared-services git hub, PR-driven applies. Roadmap.