概述
大家好,我是 Tinywan,一个在 Docker + PHP 生态里摸爬滚打好几年的老油条。
过去几年,我的 PHP 容器(Nginx + PHP-FPM + cron + 一些小脚本)几乎清一色用 supervisord 来管理多进程。配置简单,一个 ini 文件搞定所有服务,启动、重启、日志查看都挺顺手。很多老项目、公司内部镜像也都是这么玩的,稳定不出大问题,我就一直没换。
但从 2025 年下半年开始,我陆续迁移了几个核心服务到新镜像时,突然发现自己有点“跟不上时代”了。
为什么 supervisord 让我越来越不爽?
容器 stop 的时候关不干净docker stop 发 SIGTERM,supervisord 收到后会尝试优雅关闭子进程,但经常出现:主进程(supervisord 自己)不退出,导致容器卡在 “Stopping” 状态 10–30 秒,甚至要强制 kill -9。健康检查、滚动更新、蓝绿部署时特别烦。
僵尸进程(zombie)收割不彻底PHP 脚本偶尔 fork 出子进程(比如 exec() 调用 shell),supervisord 的 zombie reaping 能力一般,需要额外配置或 dumb-init 套娃。套娃多了,镜像就臃肿。
日志输出不 Docker friendly默认配置下,子进程的 stdout/stderr 会被 supervisord 接管并写文件,你得自己配置 [program:xxx] 的 stdout_logfile=syslog 或者重定向,才能让 docker logs 看到实时输出。配置一多就乱。
Python 依赖 & 体积Alpine 基础镜像里塞个 Python(哪怕是 python3-minimal),体积增加 30–50MB 左右。启动也比纯 C 的东西慢一点点。
社区趋势已经变了linuxserver.io 全家桶、Home Assistant 插件、Nextcloud 官方 fpm 镜像、serversideup/php 系列、甚至 SeleniumHQ/docker-selenium 都在 2025 年陆续提迁移到 s6-overlay 的 issue。Reddit /r/docker 里搜 “supervisord vs s6”,新帖几乎全是推荐后者。
s6-overlay 到底好在哪里?
天生为容器设计s6-overlay 的 /init 就是 PID 1,它会正确处理所有信号转发、zombie 回收、依赖启动顺序。docker stop 几乎秒退(通常 <2 秒)。
日志直接 stdout服务 run 脚本里别重定向,全部输出就进 docker logs。debug 爽翻。
极致轻量官方 noarch + arch 两个 tar.xz,加起来也就 3–5MB。纯 C + execline,无 Python 依赖。
依赖关系写得优雅用 s6-rc 的 bundle + contents.d/ 目录结构定义依赖树。比如让 nginx 等 php-fpm ready 再启动,oneshot 初始化脚本(权限、目录、环境检查)也超级好写。
readiness 通知机制加个 notification-fd 文件(内容 3),s6 就知道你的服务真正 ready 了。比 supervisord 的简单 restart 策略靠谱多了。
迁移过程(以 PHP-Nginx 为例)
- 基础镜像从 php:8.3-fpm-alpine 改成 alpine:3.21 + 手动加 s6-overlay(固定版本 3.2.x)。
- 把 supervisord.conf 删掉,改成 s6-rc 目录结构:
/etc/s6-overlay/s6-rc.d/├── nginx/│ ├── run # #!/usr/bin/execlineb -PW with-contenv nginx -g "daemon off;"│ └── notification-fd # 内容:3├── php-fpm/│ ├── run│ └── notification-fd├── init-permissions/ # oneshot 类型,启动前跑权限脚本│ ├── run│ └── type# 内容:oneshot└── user/ # 默认 bundle └── contents.d/ ├── php-fpm └── nginx
- Dockerfile 里 COPY rootfs/ / ,ENTRYPOINT ["/init"]
迁移后,镜像体积反而小了 20–40MB,docker stop 时间从 15s+ 降到 1–2s,docker logs 干净实时,健康检查也更准。
webman使用
拉取镜像
docker pull tinywan/docker-php-webman:8.4.16-s6
挂载启动webman
docker run --name webman-s6 --rm -it -p 8787:8787 -v /home/www/webman:/app tinywan/docker-php-webman:8.4.16-s6
输出日志
s6-rc: info: service s6rc-oneshot-runner: startings6-rc: info: service s6rc-oneshot-runner successfully starteds6-rc: info: service fix-attrs: startings6-rc: info: service fix-attrs successfully starteds6-rc: info: service legacy-cont-init: startings6-rc: info: service legacy-cont-init successfully starteds6-rc: info: service legacy-services: startings6-rc: info: service legacy-services successfully startedWorkerman[start.php] start in DEBUG modeMaster pid:67 is not alive-------------------------------------------- WORKERMAN ---------------------------------------------Workerman/5.1.6 PHP/8.4.16 (JIT off) Linux/6.6.87.2-microsoft-standard-WSL2--------------------------------------------- WORKERS ----------------------------------------------event-loop proto user worker listen count stateevent tcp root webman http://0.0.0.0:8787 16 [OK]event tcp root monitor none 1 [OK]----------------------------------------------------------------------------------------------------Press Ctrl+C to stop. Start success.
查看进程
$ docker top webman-s6 acxfPID TTY STAT TIME COMMAND60483 ? Ss 0:00 \_ s6-svscan60515 pts/0 Ss+ 0:00 \_ rc.init60566 pts/0 S+ 0:00 | \_ php60568 pts/0 S+ 0:00 | \_ php60569 pts/0 S+ 0:00 | \_ php60570 pts/0 S+ 0:00 | \_ php60571 pts/0 S+ 0:00 | \_ php60572 pts/0 S+ 0:00 | \_ php60573 pts/0 S+ 0:00 | \_ php60574 pts/0 S+ 0:00 | \_ php60575 pts/0 S+ 0:00 | \_ php60576 pts/0 S+ 0:00 | \_ php60577 pts/0 S+ 0:00 | \_ php60578 pts/0 S+ 0:00 | \_ php60579 pts/0 S+ 0:00 | \_ php60580 pts/0 S+ 0:00 | \_ php60581 pts/0 S+ 0:00 | \_ php60582 pts/0 S+ 0:00 | \_ php60583 pts/0 S+ 0:00 | \_ php60584 pts/0 S+ 0:00 | \_ php60516 ? S 0:00 \_ s6-supervise60519 ? Ss 0:00 | \_ s6-linux-init-s60526 ? S 0:00 \_ s6-supervise60533 ? Ss 0:00 | \_ s6-ipcserverd60527 ? S 0:00 \_ s6-supervise
最后想说
supervisord 没有错,它在 2015–2024 年几乎是 Docker 多进程的事实标准。但到了 2025–2026 年,容器哲学更纯粹了:容器应该像单个进程一样行为。s6-overlay 更贴合这个理念,轻、准、现代。
如果你还在维护老项目,supervisord 继续用没问题。但新项目、特别是 PHP + Nginx/FPM + cron 的组合,我现在是 100% 推荐 s6-overlay。
你最近有没遇到 supervisord 的痛点?或者已经在用 s6 了?欢迎交流~