首页/云/Docker 容器速查/compose init 字段启用 init 进程
Compose 编排55 条

compose init 字段启用 init 进程

init: true 让容器 PID 1 使用 init 进程转发信号并回收僵尸进程:适合直接跑脚本类、不停 fork 子进程的应用。

Docker 容器速查云更新于 2026-10-13

init 字段解决什么

Compose 的 init: true 让容器把 PID 1 交给一个轻量 init 进程(tini),由它转发信号并回收孤儿进程,等价于 docker run --init。当容器入口是 shell 脚本、并会不断 fork 子进程时,这个字段能避免 docker stop 时信号被吞,以及僵尸进程累积。

基本信息

字段init: true
等价写法docker run --init
作用信号转发 + 孤儿进程回收
适用版本Compose 文件格式 3.x 起,Compose V2 均支持
默认行为不启用,PID 1 由镜像入口命令承担

典型使用场景

  • 入口是 shell 脚本、脚本又会拉起多个后台子进程的服务
  • 长时间运行且频繁创建子进程的任务型容器
  • docker stop 后容器要等到超时才退出,怀疑信号没有被转发
  • 容器内出现僵尸进程(ps 状态为 Z)时作为低成本修复
  • 无法修改镜像入口,又需要正确的信号处理能力

Compose 写法示例

Compose 写法示例
services:
  worker:
    image: app/worker:1.4.2
    init: true                            # 由 init 进程接管 PID 1
    command: sh -c './worker.sh & wait'   # shell 包装型入口最需要它

运行期核对

运行期核对
docker top worker              # 观察进程树,init 应排在最前
docker inspect -f '{{.HostConfig.Init}}' worker   # true 表示已启用
docker stop -t 5 worker        # 验证能否快速优雅退出

启用与不启用对照

维度init: true不启用
PID 1轻量 init 进程镜像入口命令,常是 shell
信号转发由 init 负责转发shell 未写 trap 就不转发
孤儿进程回收自动回收累积为僵尸进程
停止容器收到信号后正常退出可能等到超时才被强杀
应用自身已正确实现 PID 1 职责(直接以 exec 形式启动、内部处理信号)时可以不启用;入口是脚本类服务时加上更省心。
ENTRYPOINT 用 JSON 数组形式能让应用直接成为 PID 1,比 shell 包装更干净,也能减少对 init 的依赖。
init 只保证转发与回收这条路径正确;应用本身没有处理 SIGTERM 时进程仍会被强杀,这类情况要从应用侧改。
除 init 字段外,也可以在镜像里用 dumb-init 之类的轻量 init 作为入口包装,效果等价;选择哪种取决于基础镜像生态与团队既有做法。

易错点

  • init 不解决应用自身信号处理缺失的问题,只保证转发路径正确,别指望它包治百病
  • 启用 init 后仍有僵尸进程时,要检查应用是否在该回收的地方调用 wait,而不是怀疑 init 没生效
  • 对进程数审查严格的环境里要提前说明 init 会多占一个轻量进程
  • Compose 文件格式过老时不认识 init 字段,会被静默忽略,升级前先确认版本
  • 为排查问题临时启用 init 却忘了在编排里同步,容器重建后行为又变回去,配置改动要落回编排文件

数据来源与参考

  • Docker 官方文档:Compose init 参考(docs.docker.com/reference/compose-file/services)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌