Skip to content

ADR-0010: Stage YourBOX Deployments Across docker compose, Ansible VPS, Azure And Homelab Kubernetes

Accepted

YourBOX today targets one deployment shape: an Azure Linux Web App for Docker, provisioned by a Terraform module that emits a single terraform_outputs_*.json file. The Dockerfile embeds auto_prepend_file = ".env.php" and assumes Apache. There is no path to deploy the same image to a VPS for a smoke test, no docker compose recipe, no Kubernetes manifest, no Ansible playbook.

The homelab portfolio uses Argo CD on Talos Kubernetes as the production target. Reaching that target safely needs intermediate environments: a local docker compose stack for fast feedback, a VPS for an HTTPS smoke test, an Azure stage for parity with the legacy target, and only then the Kubernetes deployment. Each stage exercises a different failure mode and gives confidence before the next.

The four targets must share one container image, one env contract (ADR-0008) and one configuration shape. Adding a target later cannot require redoing the previous ones.

YourBOX deploys through four targets in a fixed order:

  1. Local docker compose: a compose.yml at the repository root brings up YourBOX, PostgreSQL, Meilisearch, MinIO and Mailpit on the developer workstation. The compose file consumes prod.env (decrypted by SOPS) and uses Traefik for HTTPS via a local self signed certificate. This is the fastest feedback loop and runs in CI as a smoke stage.
  2. VPS via Ansible: an Ansible playbook in homelab-platform/ansible/playbooks/yourbox-vps.yml provisions Docker, copies the same compose.yml, fetches the SOPS encrypted env from the repository, decrypts it with the VPS age key and starts the stack. Traefik terminates HTTPS via ACME against the public hostname. The VPS smoke test is the public demo environment.
  3. Azure: the existing Terraform module is rewritten into smaller modules under infra/terraform/azure/. The module emits typed outputs grouped by concern (database, storage, app service, smtp) consumed by Symfony at deployment time through environment variables. The Azure provider is one of three providers; adding GCP or AWS later means adding a sibling module, not rewriting the layout.
  4. Homelab Kubernetes: a Helm chart at k8s/charts/yourbox/ packages the runtime, and a Flux Helm release plus sealed secrets at homelab-platform/kubernetes/apps/yourbox/ wires the deployment under the Argo CD app of apps. The chart consumes the same env contract from a Kubernetes Secret populated by the External Secrets Operator.

The same container image, built once per commit, deploys to all four targets. The CI pipeline builds it, scans it with Trivy, signs it with cosign and pushes it to the GitLab registry with a digest that every downstream target consumes.

A YourBOX target is considered ready only when its smoke test passes: the health endpoint returns 200, an upload + transcoding + playback round trip succeeds, and Authentik OIDC login completes. The smoke test runs in CI for the docker compose target, in the VPS deployment job for the VPS target, in the post deploy job for Azure, and via a Kubernetes job in the homelab.

  • The same image and the same configuration shape ship everywhere. A regression that manifests in one target reproduces locally on docker compose without rewriting the setup.
  • Operators can promote between targets predictably. The promotion is a deployment of the same image with a different env binding.
  • The Terraform module split forces stable interfaces between concerns (network, database, storage, runtime). Future infrastructure changes are confined.
  • The VPS is a public smoke test. It must run the same Authentik integration that production uses (or a documented stand in), so that a flow validated on the VPS gives real confidence about production.
  • Operating four targets costs CI minutes and runbook maintenance. The runbook for each target lives next to its deployment code and is referenced from the service overview.
  • Removing one target is straightforward: delete its module and its deployment job. No application code changes because the env contract stays the same.