容器Exited(0)根本原因是无前台进程:PID 1执行完即退出,需确保CMD/ENTRYPOINT启动长活前台进程,如nginx -g "daemon off;"或tail -f /dev/null(仅调试)。
容器启动后立刻退出并显示 exited (0),不是报错,而是“太守规矩”——它按设计完成了任务就收工了。根本原因只有一个:容器里没有持续运行的前台进程。
误区一:把容器当虚拟机用,忘了它的生命周期逻辑
Docker 容器不是 mini-VM,它不维护操作系统级后台服务(比如 systemd)。它的整个生命周期只绑定一个进程(PID 1),这个进程结束,容器就停。很多人写 Dockerfile 时习惯性沿用传统部署方式,比如:
- 用
CMD ["service nginx start"]—— 这条命令执行完就退出,Nginx 被后台化,PID 1 消失 - 用
CMD ["sh", "-c", "python app.py &"]——&把主进程放后台,前台 shell 立刻结束 - 直接运行一次性脚本(如初始化数据库、打印日志后 exit)——任务完成即退出,状态码自然为 0
误区二:误以为加 -d 就能“常驻”,其实只是后台运行而已
docker run -d 只是让容器在后台运行,不解决根本问题。如果 PID 1 还是秒退,它照样 Exited (0)。常见错误操作:
-
docker run -d ubuntu echo "hello"→ 打印完就退出,状态码 0 -
docker run -d nginx:alpine→ 如果镜像没配好前台启动方式,也可能闪退(官方镜像已修复,但自定义镜像易踩坑)
误区三:混淆健康检查与主进程存活机制
有人给容器加了 livenessProbe,发现它反复重启,却查不到错误日志——其实是因为容器每次启动都成功返回 0,然后立刻退出,探针还没来得及发请求,容器已经没了。这不是健康检查失败,而是主进程压根没撑住。
典型表现:docker ps -a 显示大量重复容器,状态都是 Exited (0),docker logs 空或只有启动信息。
正确解法:确保 PID 1 是长活前台进程
核心原则:让 CMD 或 ENTRYPOINT 启动的命令一直不退出。常用方式:
-
用官方推荐的前台模式:Nginx 加
-g "daemon off;";Redis 加--daemonize no;Tomcat 用catalina.sh run(不是 start) - 兜底方案:用 tail -f /dev/null 或 sleep infinity(仅调试/临时用途,生产环境慎用)
-
业务应用需主动阻塞:Python 用
app.run(host='0.0.0.0', port=8000);Node.js 用server.listen()并监听 SIGTERM;Java Spring Boot 默认就是前台运行 -
多进程场景加 init 系统:用
tini作为 ENTRYPOINT,避免僵尸进程干扰主进程生命周期

















