如何通过Dockerfile运行uvicorn服务与Python常驻脚本两个进程?
解决Docker中同时运行两个常驻Python进程的问题
因为uvicorn和你的ManagerBot.py都是常驻进程,直接用;或&&串联命令时,第一个进程会一直占用终端,导致第二个进程永远无法启动。以下是几种可行的解决方法:
方法1:使用启动Shell脚本
创建一个专门的启动脚本,将两个进程后台运行,再通过wait让容器保持运行:
- 在项目根目录创建
start.sh脚本:
#!/bin/bash cd Manager # 后台启动uvicorn,可指定日志输出路径(可选) uvicorn ManagerBot:app --host 0.0.0.0 --port 8000 & # 后台启动Python脚本,同样可选日志输出 python ManagerBot.py & # 等待所有后台进程,防止容器启动后立即退出 wait
- 给脚本添加执行权限,并在Dockerfile中配置:
# 复制启动脚本到容器 COPY start.sh /start.sh # 添加执行权限 RUN chmod +x /start.sh # 执行启动脚本 CMD ["/start.sh"]
方法2:直接在CMD中后台运行进程
无需额外脚本,直接在CMD中将两个进程后台启动,并用tail -f保持容器存活:
CMD cd Manager && \ nohup uvicorn ManagerBot:app --host 0.0.0.0 --port 8000 > uvicorn.log 2>&1 & \ nohup python ManagerBot.py > bot.log 2>&1 & \ tail -f /dev/null
nohup用于让进程脱离终端运行,即使主进程退出也能继续执行> uvicorn.log 2>&1将日志输出到文件,方便后续排查问题tail -f /dev/null用来维持容器的运行状态,否则容器会在后台进程启动后立即退出
方法3:使用Supervisor进程管理工具
如果需要更规范的进程管理(比如自动重启崩溃的进程),可以用Supervisor:
- 在Dockerfile中安装Supervisor:
RUN apt-get update && apt-get install -y supervisor
- 创建Supervisor配置文件
supervisor.conf:
[supervisord] nodaemon=true # 让Supervisor在前台运行,避免容器退出 [program:uvicorn] directory=/Manager # 进程工作目录 command=uvicorn ManagerBot:app --host 0.0.0.0 --port 8000 stdout_logfile=/dev/stdout # 将日志输出到容器stdout,方便docker logs查看 stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 [program:managerbot] directory=/Manager command=python ManagerBot.py stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0
- 在Dockerfile中复制配置并启动Supervisor:
COPY supervisor.conf /etc/supervisor/conf.d/ CMD ["supervisord", "-n"]
这三种方法都能解决你遇到的问题,其中方法1最简单,适合简单的双进程场景;方法3更适合需要进程监控的复杂场景。
内容的提问来源于stack exchange,提问作者Andrea Basile
相关产品推荐
相关产品推荐

