Docker 中运行多个进程
FreeGuideOnline
最新
2026-07-07
. ├── Dockerfile └── start.sh
### 编写启动脚本 `start.sh`
```bash
#!/bin/bash
set -e
# 启动第一个进程(Web 服务)
/app/web-server &
# 启动第二个进程(后台 worker)
/app/worker &
# 等待任意一个进程退出
wait -n
# 如果任何进程退出,则终止其他进程并退出容器
exit $?
编写 Dockerfile
FROM ubuntu:22.04
COPY start.sh /start.sh
RUN chmod +x /start.sh
COPY ./app /app
CMD ["/start.sh"]
注意事项
- 必须在脚本中使用
wait,否则脚本会直接退出导致容器结束。 wait -n会在任意子进程退出时返回,适合“任一失败则整体退出”的逻辑。- 进程不会被自动重启,一旦某个后台进程意外退出,整个容器将终止。
这种方法仅推荐用于开发或快速验证,不适合生产环境。
方法二:使用 Supervisor(生产环境常用)
Supervisor 是一个轻量的进程控制系统,能够监控并自动重启指定进程,非常适合在容器内管理多进程。
安装 Supervisor
在 Dockerfile 中安装 Supervisor。以 Debian/Ubuntu 基础镜像为例:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY ./app /app
CMD ["/usr/bin/supervisord"]
编写 Supervisor 配置文件
创建 supervisord.conf,定义需要监管的每个程序。
[supervisord]
nodaemon=true # 以前台模式运行,避免容器退出
logfile=/dev/stdout # 将 supervisord 自身的日志输出到标准输出
logfile_maxbytes=0
[program:web]
command=/app/web-server
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
[program:worker]
command=/app/worker
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
关键配置说明:
nodaemon=true:必须设置,否则 supervisord 会以守护进程方式后台运行,导致容器立即退出。autorestart=true:进程异常退出后自动重启。- 日志输出到
/dev/stdout和/dev/stderr,方便通过docker logs查看。
构建与运行
docker build -t multi-process-app .
docker run --name app multi-process-app
使用 docker exec -it app supervisorctl status 可以查看各进程状态:
web RUNNING pid 12, uptime 0:05:32
worker RUNNING pid 13, uptime 0:05:32
如果手动停止一个进程,Supervisor 会立即将其重新拉起。
方法三:使用更轻量的进程管理器(s6-overlay)
如果你不想引入 Python 依赖(Supervisor 基于 Python),也可以选择 s6-overlay。它由一组极小的 C 程序组成,专门为容器场景设计,内置进程监控、日志重定向和优雅关闭等功能。
使用 s6-overlay 的 Dockerfile
FROM ubuntu:22.04
ARG S6_OVERLAY_VERSION=3.1.6.2
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz && \
tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz && \
rm /tmp/s6-overlay-*.tar.xz
COPY ./app /app
COPY ./s6-rc.d /etc/s6-overlay/s6-rc.d
ENTRYPOINT ["/init"]
编写服务定义
在 s6-rc.d 目录下为每个服务创建子目录,包含一个 run 脚本。例如 Web 服务:
s6-rc.d/web/run(需可执行权限)
#!/command/with-contenv sh
exec /app/web-server