ECS Fargate中Docker容器执行脚本后退出码0 无法进入/bin/sh如何解决
核心问题定位
- 退出码为0代表容器主进程(即配置的
/tmp/init.sh脚本)是正常执行完成后退出,并非崩溃或异常终止 - ECS任务中标记为Essential的容器退出时,整个任务会被标记为失败并停止,属于ECS的默认机制
- 本地执行
docker run -it application /bin/sh无法进入容器的原因是:你指定了ENTRYPOINT后,命令行末尾追加的内容会被作为ENTRYPOINT的参数传入,而非替换ENTRYPOINT,实际执行的命令为/tmp/init.sh /bin/sh,脚本执行完成后容器直接退出,自然无法进入交互模式
排查步骤
- 首先验证容器本身可正常进入,本地执行覆盖ENTRYPOINT的启动命令:
docker run -it --entrypoint /bin/sh application,即可进入容器交互环境 - 进入容器后查看
/tmp/init.sh的完整逻辑,重点检查脚本末尾是否启动了前台常驻进程:比如Web服务、业务常驻程序等需要持续运行的进程。如果脚本仅执行初始化配置、没有启动任何常驻进程,脚本执行完成后主进程就会退出,容器也会随之停止 - 本地不覆盖ENTRYPOINT直接运行容器,执行
docker run application,查看控制台输出的脚本执行日志,确认脚本执行流程是否符合预期,是否执行完成后直接退出 - 检查脚本中业务进程的启动方式:如果业务进程添加了
&符号放在后台运行,主进程仍然是/tmp/init.sh,脚本执行完成后还是会退出,需要将业务进程放在前台作为主进程运行
解决方案
根据实际场景选择对应修复方式:
- 若
/tmp/init.sh需要先执行初始化再启动业务进程:在脚本末尾使用exec命令启动业务进程,替换当前shell主进程,确保业务进程成为容器主进程,示例如下:
exec /usr/local/bin/your-business-service --config /etc/service/config.yaml
- 若
/tmp/init.sh仅为一次性初始化任务、不需要常驻运行:将ECS任务类型调整为一次性执行的任务(而非长期运行的服务类任务)即可 - 若需要保留ENTRYPOINT配置同时支持自定义命令调试:可以修改
/tmp/init.sh逻辑,增加参数判断逻辑,当传入外部命令时直接执行传入的命令,无需执行原有初始化逻辑,方便后续调试
内容的提问来源于stack exchange,提问作者Dave Michaels
相关产品推荐
相关产品推荐

