/var/www/xnett.org/containers/building-a-production-ready-linux-docker-host.md
[CONTAINERS]Building a production-ready Linux Docker host
Building a Linux container platform with Docker, networking, reverse proxy, monitoring and backup.
- author:
- Rolf
- date:
- 2026-09-07 23:54
- read:
- ~2 min
A single well-configured Docker host can comfortably run a handful of small production services for years. The difference between "comfortably" and "a 2am pager incident" mostly comes down to a few decisions made up front.
Daemon configuration
Docker's defaults are tuned for developer laptops, not hosts that stay up for months. Log rotation is the one that bites people first — without it, a chatty container will happily fill the disk with JSON log files.
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2"
}Drop that in /etc/docker/daemon.json and restart the daemon.
One reverse proxy, many services
Rather than giving every service its own TLS termination and port, a single reverse proxy container in front of everything keeps certificate management and routing in one place. Each application service joins a shared external Docker network; the proxy is the only thing that binds to 80/443 on the host.
services:
app:
build: .
restart: unless-stopped
networks:
- gateway-net
networks:
gateway-net:
external: trueThe proxy's own config then gets one new block per domain, pointing at the service's container name and internal port. Caddy is a good fit here specifically because it handles Let's Encrypt certificate issuance and renewal automatically — no separate certbot timer to babysit.
Keeping the proxy as its own long-lived container — separate from any single application's compose stack — means you can redeploy an app (even destroy and recreate its container) without touching the TLS layer at all.
Monitoring and backup
A host isn't production-ready just because it's running; you need to know when it stops behaving. A small Prometheus + Grafana + node-exporter stack covers host-level metrics (CPU, memory, disk) with very little resource overhead, and container-level metrics via cAdvisor if you need per-service visibility.
For backups, the pattern that's worked reliably for me is boring on purpose: a nightly script tars up application data volumes and any embedded database file, encrypts the archive, and keeps a rolling window of the last N backups. Boring is a feature — the fewer moving parts in the backup path, the more you can trust it when you actually need to restore from it.
tar -czf - ./data | openssl enc -aes-256-cbc -pbkdf2 -pass file:/root/.backup_key > backup_$(date +%F).tar.gz.encNone of this is exotic. It's a handful of deliberate, individually simple choices that add up to a host you don't have to think about most days.
# EOF