Docker-Compose启动容器退出码为0的原因排查求助
容器启动后立即退出(Exited (0))的原因及修复方案
你的问题核心出在start.sh脚本里的后台运行符号&,以及Docker容器的运行机制上——我来给你拆解清楚:
为什么会退出?
Docker容器的生命周期是和主进程绑定的:只要主进程结束,容器就会立刻停止(退出码0说明是正常结束)。
你在start.sh里给gunicorn命令加上了&,这会让gunicorn在后台运行,脚本执行完这条命令后就直接结束了——此时容器的主进程(就是这个start.sh脚本)已经完成任务退出,容器自然也就跟着停了。
至于单独用Docker运行正常,大概率是你手动启动时还有其他交互操作(比如进入容器shell),但docker-compose是直接启动容器并监控主进程,所以脚本一结束容器就退出了。
两种修复方法
方法1:让gunicorn在前台运行(推荐)
这是最标准的做法,把gunicorn作为容器的主进程,只要它不崩溃,容器就会一直运行。修改你的start.sh:
#!/bin/bash # 去掉末尾的&,让gunicorn在前台执行 gunicorn --chdir hello --bind :8000 hello_django.wsgi:application
方法2:用wait命令让脚本保持运行
如果你确实需要把gunicorn放后台(比如还要启动其他服务),可以在脚本最后加上wait命令,让脚本一直等待所有后台进程结束,这样容器就不会提前退出:
#!/bin/bash gunicorn --chdir hello --bind :8000 hello_django.wsgi:application & # 等待所有后台进程,防止脚本提前结束 wait
额外排查技巧
- 先看容器日志确认情况:运行
docker-compose logs djangoapp,能看到gunicorn是否启动过,以及脚本的执行日志 - 临时调试:修改
docker-compose.yml让容器启动后进入shell,手动执行脚本观察问题:
然后运行services: djangoapp: build: . volumes: - .:/opt/services/djangoapp/src ports: - 8000:8000 command: bash # 替换ENTRYPOINT,直接进入交互shelldocker-compose up,再新开终端执行docker-compose exec djangoapp bash进入容器,手动运行./start.sh就能看到具体执行情况了。
内容的提问来源于stack exchange,提问作者amit yadav




