fairlane.systems

DOCKER · TECH STACK

Docker orchestration for SMEs: docker-compose without Kubernetes overkill

Docker + docker-compose is enough for single-host setups up to 50 containers. Digest pinning, healthchecks, restart policies, resource limits, non-root.

Researched & fact-checked by: · As of: 2026-05

What is Docker orchestration?

Docker orchestration is the practice of declaratively describing, starting, monitoring, and restarting multiple container processes on one or more hosts. In Swiss SME setups, "orchestration" is often misread: many hear the word and immediately picture Kubernetes – and with it a cluster with three masters, etcd, an ingress controller, a CNI, and a CSI plugin. For the typical fiduciary or SME infrastructure with ten to thirty containers, that stack is over-dimensioned and expensive.

The calm alternative is Docker Engine plus docker-compose. Compose has been stable at version 2.27 since May 2026, is maintained by Docker itself, and describes a full application stack in a single YAML file. On a Hetzner dedicated server with 64 GB of RAM, 25 production containers run without trouble. The Fairlane server itself uses exactly this pattern: 25 production containers, one central docker-compose.yml per logical group (monitoring, AI, databases, workflow), governed by systemd unit files for boot order and restart behaviour. Complexity stays at a level a single operator can maintain.

Why it matters

Poorly set up containers eat memory, open needless ports, and lose logs after the first restart. A fiduciary office cannot afford to fix a broken container every week. Cleanly orchestrated containers behave like screwed-shut drawers: each runs under defined limits, each restarts after a power outage without intervention, each writes structured logs to a central sink.

In practice that means: the application can be moved to a new server in under an hour, because the compose.yml plus three volumes is the complete state. Security updates for the base image are traceable and roll out per container. In an audit under Art. 957a CO or VDSG/revDSG it is provable which software version ran when. And hosting costs stay predictable – no hidden cluster fees, no load balancer per service, no end-of-month egress traffic shock.

How it works

A production-ready Compose setup follows six rules, each small on its own and together the difference between "it runs" and "it has been running untouched for two years".

Image pinning by digest. Instead of `image: postgres:16`, write `image: postgres:16@sha256:abc123...`. That stops a re-pull from grabbing a different build. Renovate or Watchtower-with-stop-mode then updates the digest under control.

Healthchecks per container. Every container has a `healthcheck:` block that probes its own service – `pg_isready` for Postgres, `curl --fail` for an HTTP service. Compose starts dependent containers only when the healthcheck reports `healthy` (`depends_on: condition: service_healthy`).

Restart policies. For long-running services `restart: unless-stopped`. For cron-like containers `restart: no`. Never `restart: always` without a healthcheck – a broken container would respawn in a loop and burn CPU.

Log rotation. Default driver json-file with `options: max-size: 10m, max-file: 5`. Without those two lines, logs grow without bound. At Fairlane, logs also stream through the loki-docker-driver into Loki.

Resource limits. `mem_limit: 512m` and `cpus: "1.0"` keep a single container from suffocating the host. Without limits, a memory leak in one n8n workflow can drag down everything else.

Non-root user. Set `USER 1000:1000` in the Dockerfile. Compose additionally allows `user: "1000:1000"` and `read_only: true` for filesystem lockdown. A container-escape vulnerability then no longer translates automatically into a host-root vulnerability.

Compose setup in 7 steps

  1. 01Install Docker Engine + Compose plugin (apt-get docker-ce docker-compose-plugin, Ubuntu 24.04 LTS).
  2. 02One compose.yml per logical group: monitoring, ai, data, workflow. Not all 25 containers in one file.
  3. 03Pin every image by digest, hook up a Renovate bot for controlled updates.
  4. 04Healthcheck block per container – pg_isready, curl --fail /healthz, redis-cli ping.
  5. 05Set resource limits: mem_limit, cpus. Default 512m / 1 CPU, then adjust per service.
  6. 06Configure log driver: json-file max-size 10m max-file 5, or loki-driver for central logging.
  7. 07systemd unit per compose.yml: ExecStart=docker compose up, ExecStop=docker compose down. The stack survives every reboot.

When to use docker-compose

Docker-compose is the right choice when (a) the whole stack runs on one or two hosts, (b) the operations team is one to three people, and (c) the availability requirement is "a few minutes of downtime is tolerable". That covers almost every Swiss SME under 200 employees.

Typical use cases: self-hosted n8n plus Postgres plus Redis for workflow automation. A RAG setup with Qdrant plus LiteLLM gateway plus Ollama. A monitoring stack of Grafana, Prometheus, Loki, and Promtail. An internal tooling server with Gitea, Drone, Plausible. In all these cases, Kubernetes or Nomad is measurably more work for zero added value.

When not to use

Docker-compose hits limits when (a) the stack must span more than three hosts and services should migrate automatically between nodes, (b) a single service needs hundreds of replicas and a service mesh becomes mandatory, or (c) a hyperscaler managed-Kubernetes offering (GKE, EKS) is already the internal standard.

More anti-patterns: docker-compose in production without a systemd wrapper – Compose alone does not reliably start a stack on reboot. Compose files with hard-coded plaintext secrets – use .env with `chmod 600` or Docker secrets instead. Privileged containers without a clear reason – `privileged: true` disables almost every Linux security boundary and is superfluous in 95% of cases (use targeted `cap_add:` instead).

Trade-offs

STRENGTHS

  • One operator can run 25+ containers cleanly
  • Entire stack reproducible from a single YAML file
  • Predictable cost: no cluster fees, no load-balancer sprawl
  • Migration to a new host in under an hour

WEAKNESSES

  • No automatic failover between hosts
  • Horizontal scaling is manual only, not reactive
  • Rolling updates must be constructed explicitly, not built in
  • Beyond 50 containers Compose becomes hard to oversee

FAQ

Do I need Docker Swarm or Kubernetes for high availability?

For 99.5% uptime: no. A single well-maintained host with Compose plus daily volume backups delivers 99.9% in practice – most outages come from software bugs, not hardware. True active-active HA with automatic failover needs either Swarm (simple) or Kubernetes (complex) plus shared storage. Only above a 99.95% availability target does the extra effort pay off.

How do I update containers without downtime?

For stateless containers: bring up a second Compose instance in parallel, switch the nginx upstream, shut down the old instance. For stateful containers like Postgres: announce a short maintenance window (30–60 seconds) and run docker compose up -d with the new digest. Major upgrades (Postgres 16 to 17) need pg_upgrade and are not a Compose topic.

What does a Compose setup cost compared to Kubernetes?

One-time setup: 2–4 days for 20 containers. Ongoing operations: about 1–2 hours per month. A managed Kubernetes cluster (GKE Autopilot, AKS) costs at least CHF 200/month for control plane plus three nodes, on top of Helm chart, ingress, cert-manager, and monitoring work. Factor 5–10 in operational effort.

Related topics

NGINX · TECH STACKNginx as reverse proxy: SSL, rate limits, and security headers for containerised appsSERVER & INFRASTRUCTURE · SERVICEServer & Infrastructure: Ubuntu, Docker, monitoring – set up, hardened, handed overHETZNER · TECHHetzner as EU hosting for Swiss fiduciaries and SMEs: data centres, contracts, costGRAFANA · TECH STACKGrafana, Prometheus, Loki: monitoring stack for container apps and LLM workflowsMANAGED · SERVICEManaged Service & Monitoring: we keep it running, you use it

Sources

  1. Docker Documentation – Compose Specification v2.27 · 2026-05
  2. OCI Image Specification – Digest-based pinning · 2026-02
  3. Docker Security Best Practices – non-root, read_only, cap_drop · 2026-04
  4. CNCF Annual Survey 2025 – Compose vs Kubernetes adoption in SMEs · 2025-12

FITS YOUR STACK?

What this looks like in your business – a 30-minute intro call.

Book a call