Run platform services as composed containers on a single host
Docker Compose on one Linux host rather than a container orchestrator, for as long as the workload genuinely fits.
- Runtime
- Infrastructure
- Operations
2 min read · 512 words
The forces at the time
What was chosen
edge network is shared with the reverse proxy and carries only what is meant to be reachable. A data network is marked internal and has no route off the host. Databases attach only to data . No service publishes a host port.
services:
api:
build: ./api
depends_on: [db, broker]
networks: [edge, data]
# No published ports. The proxy is the only way in.
db:
image: postgres:16-alpine
volumes: [pgdata:/var/lib/postgresql/data]
networks: [data]
networks:
edge: { external: true } # shared with the reverse proxy
data: { internal: true } # no route off the hostWhat else was considered
- Kubernetes
- Rejected for this scale. A control plane is itself a system to operate, upgrade, and debug, and its value is in scheduling across nodes — capability that does not apply to one machine.
- Docker Swarm
- Rejected. Lighter than Kubernetes and closer to the Compose file format, but it still introduces cluster state to manage in exchange for multi-node scheduling that is not needed.
- Systemd units on the host
- Rejected. Fewer moving parts and excellent supervision, but dependency isolation becomes the host’s problem and rebuilding the machine stops being reliable.
- A managed cloud platform
- Rejected. The point of this platform is that it runs on hardware under direct control, on the same network as the devices it serves. That requirement is the project, not an implementation choice.
What follows
Gained
- The full runtime definition is a handful of readable files in version control.
- A rebuild is a checkout and a compose up, which makes reproducibility testable rather than theoretical.
- No control plane to operate, upgrade, or debug at 1am.
- Internal networks give the database no route off the host regardless of service behaviour.
Paid for
- The host is a single point of failure. Maintenance is downtime.
- No automatic rescheduling. A failed container restarts in place or not at all.
- Scaling beyond one machine means replacing this decision, not extending it.
- Compose does not cover secret management, which needs a separate answer.
Records are immutable once accepted. A change supersedes this one rather than editing it.