Choosing a path
Both paths run the same images and the same database schema. They differ in what they include, how they are operated and how much the release tooling does for you.
Docker Compose | Kubernetes | |
|---|---|---|
Status in the repository | The default target | Kept for an explicit switch: the scripts refuse to run unless |
Manifest |
|
|
Cluster or host | One Linux machine with Docker Engine and Compose v2 | k3s 1.32 or later with its bundled Traefik |
Identity provider | Bring your own OpenID Connect provider | Zitadel included, at |
Workers | Five containers, one role each | One combined worker running all five roles |
Sites | Optional, through the | Included; sites are served at |
Public ingress | A Cloudflare Tunnel connector, or your own reverse proxy | Traefik Ingresses that admit only Cloudflare's edge, with an origin certificate |
Releases |
|
|
Backups |
| A nightly CronJob writes dumps and a storage archive to a volume on the same node |
Network isolation | One private Compose network | NetworkPolicies limit who may reach the object store and the broker, and where workers may connect |
When to choose which#
Choose Docker Compose if you want the most complete release tooling, already run an identity provider, or want the simplest thing to reason about at 2am. It is the path with verified backups and an automated smoke test.
Choose Kubernetes if you already run k3s, want Zitadel and Sites deployed alongside Nix in one step, and are happy to arrange off-node backup copies yourself. The manifests are sized to fit a small single node: one combined worker, one replica of each service and modest memory limits.
Either way, keep the rules that apply to both: run images by full commit SHA, take a backup before every upgrade, and never let a migration and an old image run against each other.