Docker Compose vs a Process Manager for Self-Hosting
Once you have more than one process to run — an app, a worker, maybe a database — you need something to orchestrate them. On a single server, the two common answers are Docker Compose and a process manager. They overlap enough that the choice is genuinely unclear, so let’s compare them on the things that actually matter.
What each one is really doing
Docker Compose describes a set of containers — isolated filesystems and process namespaces — and the network between them. Its restart policies keep containers alive; its depends_on orders startup.
A process manager describes a set of processes running directly on the host. It keeps them alive, restarts on crash, runs health checks, and manages logs — but they share the host’s filesystem and libraries.
The core trade is isolation vs. weight. Containers isolate; that isolation costs image builds, a daemon, and overhead. Processes are light; the cost is that they share the host.
Head to head
| Docker Compose | Process manager | |
|---|---|---|
| Isolation | Strong (namespaces, own FS) | Shared host |
| Dependency bundling | In the image | On the host |
| Resource overhead | Docker daemon + per-container | Minimal |
| Startup speed | Slower (container start) | Fast (process spawn) |
| Reproducibility | Excellent (pinned images) | Depends on host setup |
| Deploy | Rebuild/pull image | Pull + reload |
| Debugging | docker logs, exec into container | htop, direct log files |
| Zero-downtime reload | Awkward | Built in |
| Crash recovery | restart: always | Health-gated, with backoff |
Where Docker Compose wins
- Dependency hell is real and containers make it go away. If your app needs a specific system library, an exact Python version, or ImageMagick with the right delegates, baking it into an image is cleaner than fighting the host.
- Reproducibility. A pinned image runs the same on your laptop and the server. “Works on my machine” mostly dies.
- Third-party services. Spinning up Postgres, Redis, and your app together with one
docker compose upis genuinely nice. - Blast-radius isolation. A misbehaving container can’t scribble on the host filesystem.
Where a process manager wins
- Resource cost on small boxes. The Docker daemon plus per-container overhead is noticeable on a 1 GB VPS. A Rust process manager supervising native processes costs a few megabytes total.
- Deploy and reload ergonomics.
oxmgr reload apidoes a readiness-gated rolling restart in place. Doing the equivalent with Compose usually means a second container and a proxy switch. - Debugging directness. The process is right there.
htop,strace, a log file, aSIGUSR2— nodocker execlayer between you and the program. - Startup latency. Process spawn is milliseconds; container start is seconds. It matters for fast crash recovery.
The move most people miss: use both
These aren’t mutually exclusive, and the best single-server setups often combine them:
Pattern A — Compose for backing services, process manager for your app. Run Postgres and Redis in Docker (where reproducibility helps most), and run your application under a process manager directly on the host (where deploy ergonomics and low overhead help most). Your app connects to localhost:5432. You get pinned dependencies where they matter and fast, health-gated reloads where you deploy constantly.
Pattern B — process manager inside the container. When you do containerize the app, you often still want more than node server.js as PID 1 — a supervisor that handles signals, restarts a crashed worker, and reaps zombies. A tiny static-binary process manager as the container entrypoint gives you graceful shutdown and multi-process supervision without dragging Node into your init layer.
How to choose
Ask what’s actually hard about your deploy:
- Dependencies / reproducibility is the pain → Docker Compose (at least for the parts with heavy deps).
- Overhead, deploy speed, and debugging are the pain → process manager on the host.
- You have both pains → Pattern A: Compose for services, process manager for the app.
There’s no universal winner. Compose gives you isolation and reproducibility; a process manager gives you lightness and operational directness. On a single self-hosted box, the pragmatic answer is usually not “one or the other” but “the container where it earns its overhead, the process manager everywhere else.”