Skip to content

ADR-0001 — Single-node Docker Compose, no orchestrator

  • Status: accepted
  • Date: 2026-06-30
  • Domain: runtime architecture · operations

Context

data-lab runs several small, independent services — a reverse proxy, a portfolio site, container management, and a growing set of data projects — on a single Hetzner VPS with a tight RAM budget and no swap at the time this was decided. It is a solo project whose purpose is learning and portfolio visibility: there is no uptime SLA, no team, and no requirement for high availability. The lab is also meant to be legible — a reviewer should be able to read the setup and understand it quickly. Deployments happen frequently (push-to-live in under a minute). The question is what runs and schedules the containers: a full orchestrator, or something simpler.

Decision

Plain Docker Compose on a single host. Even k3s — the lightest credible orchestrator — carries a control-plane and agent footprint that is hard to justify against a RAM budget the data workloads themselves need. Every feature an orchestrator provides (autoscaling, self-healing across nodes, rolling updates, multi-node scheduling) solves a problem this single-box, no-SLA lab does not have. Compose gives a declarative, version-controlled description of each service with effectively zero control-plane overhead, and the deploy step is a trivial docker compose pull && up -d. The simplicity is a feature in its own right: the whole system fits in one person's head.

Consequences

  • Minimal moving parts; the entire runtime is docker + compose files in git. The control plane costs nothing — all RAM goes to actual services. Deploys are simple, fast, and easy to explain, which serves the portfolio goal directly.
  • No high availability — the single host is a single point of failure — and no rolling updatesup -d causes a brief drop for the service being replaced. No autoscaling or self-healing across nodes: a crashed host stays down until manual intervention.
  • Operating multiple heavy backing services at once (e.g. Kafka + Airflow + MinIO simultaneously) is not feasible on this hardware regardless of how they are scheduled — this shapes every later service-selection decision (see ADR-0006, ADR-0008).
  • Per-project compose files keep the door open: a project can be lifted onto k3s later without redesign if a genuine multi-node need appears. Revisit if a workload needs more than one node, RAM stays saturated after vertical scaling, or zero-downtime deploys become a hard requirement.

Alternatives considered

  • Kubernetes (k3s or full k8s) — rejected: control-plane and agent footprint is hard to justify against the RAM budget; the HA/autoscaling it buys solves a problem this lab doesn't have.
  • Docker Swarm — rejected: lighter than k8s but still a multi-node cluster model for a single-node lab; no reason to carry the coordination machinery.
  • HashiCorp Nomad — rejected: a capable scheduler, but scheduling is not the bottleneck here — there is only one host to schedule onto.