Alternative to supervisord for Docker
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
If you are reaching for supervisord inside a Docker container, the first question is whether you should be running multiple long-lived processes there at all. In many cases the better alternative is not another supervisor, but a different container layout.
Prefer One Service Per Container
Docker works best when one container runs one main service. Separate services can then be coordinated with Docker Compose, Kubernetes, or another orchestrator.
For example, instead of running a web server and a worker under supervisord in one image, run them as two services from the same build.
This makes health checks, logs, restarts, and scaling much simpler. If the worker crashes, it can be restarted independently without coupling its lifecycle to the web process.
If You Only Need a Proper PID 1, Use tini
Sometimes people install supervisord only because signal handling or zombie reaping is broken. That is a different problem. In that case, a small init process such as tini is the right tool.
tini does not supervise multiple independent services. It just behaves correctly as PID 1 by forwarding signals and reaping child processes.
For Real Multi-Process Containers, Use a Lightweight Supervisor
If you truly must run multiple services in one container, choose a tool designed for containers rather than defaulting to supervisord out of habit.
Two common options are:
- '
s6-overlayfor robust service supervision' - '
runitfor a simpler Unix-style supervisor'
s6-overlay is a good fit when you need ordered startup, automatic restarts, and explicit service directories. It is more container-oriented than a generic process manager, but it also adds setup complexity. That tradeoff is worth it only when the single-container design is intentional and justified.
A Simple Shell Wrapper Is Sometimes Enough
If the container just needs one short helper process before starting the main server, a shell script may be enough.
Use exec for the final process so it replaces the shell and receives signals correctly. This pattern is appropriate for setup tasks, not for supervising two unrelated daemons forever.
In Compose, that can be wired directly:
How to Choose the Right Alternative
A practical decision rule is:
- if you have multiple services, split them into multiple containers
- if you have one service but need correct PID 1 behavior, use
tini - if you truly need multiple long-lived processes in one container, use
s6-overlayorrunit - if you only need pre-start setup, use a shell entrypoint with
exec
That framing is more useful than searching for a one-to-one replacement for supervisord, because the best answer depends on the actual reason it was added.
Common Pitfalls
The main mistake is using supervisord to hide a poor container boundary. If the services can run separately, a supervisor inside one container is usually added complexity.
Another issue is confusing init behavior with supervision. If the real problem is signal handling, a tiny init process is enough.
A third mistake is writing a shell wrapper that forgets exec, which leaves the shell as PID 1 and brings the signal-handling problem back.
Summary
- The best alternative to
supervisordis often splitting services into separate containers. - Use
tiniwhen you need correct PID 1 behavior for a single main process. - Use
s6-overlayorrunitonly when a multi-process container is truly required. - Use a small shell entrypoint for one-time setup tasks before the main process starts.
- Pick the tool based on the failure mode, not on habit.

