Docker容器化脚本直接运行与进入容器执行的行为差异原因
Docker容器直接运行WebSocket脚本无通知的原因分析
问题场景
使用基于websocket-client库的Python脚本_wsdump.py发送WebSocket通知,配套启动脚本script.sh和Dockerfile配置如下:
script.sh内容
#!/bin/sh set -o allexport . /root/.env set env python3 /utils/_wsdump.py "wss://mywebsocketserver:3000/message" -t "message" &
Dockerfile内容
FROM python:3.8-slim-buster RUN set -xe \ pip install --upgrade pip wheel && \ pip3 install websocket-client ENV TZ="Europe/Rome" ADD utils/_wsdump.py /utils/_wsdump.py ADD .env /root/.env ADD script.sh / ENTRYPOINT ["./script.sh"] CMD []
出现异常:
- 执行
docker run -it --entrypoint=/bin/bash mycontainer进入容器后手动调用script.sh,能正常收到通知; - 直接执行
docker run mycontainer无报错,但收不到任何通知。
核心原因
1. 容器主进程生命周期绑定问题
Docker容器的存活完全依赖主进程:主进程退出,容器会立即停止并销毁所有子进程。
你的script.sh最后一行把Python客户端命令放到后台运行(&符号),脚本执行完这一行后没有后续任务,主进程(script.sh)直接退出,容器随之停止,后台的Python进程被强制终止,自然无法持续连接WebSocket服务器接收通知。
2. 交互式运行的差异
当用-it --entrypoint=/bin/bash启动容器时,容器的主进程是交互式bash会话。你手动执行script.sh后,Python进程在后台运行,但bash一直处于活跃状态(等待用户输入),容器不会停止,所以Python进程能持续运行并接收通知。
解决方案
方案一:让Python进程成为脚本主进程
去掉Python命令后的&,让脚本等待Python进程结束,容器会随Python进程的生命周期保持运行:
# 修改script.sh最后一行 python3 /utils/_wsdump.py "wss://mywebsocketserver:3000/message" -t "message"
方案二:用wait命令等待后台进程
如果需要在后台运行Python进程同时执行其他任务,可在脚本末尾添加wait命令,让主进程(script.sh)等待所有后台进程结束:
# 修改script.sh python3 /utils/_wsdump.py "wss://mywebsocketserver:3000/message" -t "message" & wait
内容的提问来源于stack exchange,提问作者Kambei
相关产品推荐
相关产品推荐

