如何在Docker中同时运行Django应用与自定义manage.py命令进程
解决Docker中同时启动Django应用和task_process的问题
先分析你之前脚本的问题
你之前的几个脚本失败的核心原因:
- 带
exec的写法:exec会直接替换当前的shell进程,比如exec gunicorn...&会把shell变成gunicorn进程并后台运行,此时原shell已经不存在,后续的python manage.py task_process根本不会执行。 - 第四个脚本先前台运行gunicorn:只有等gunicorn退出后才会执行task_process,而gunicorn是常驻进程,所以task_process永远不会启动。
快速解决方案:修正startup.sh脚本
直接用普通后台启动gunicorn,然后前台运行task_process(Docker容器会以PID 1的前台进程为准,保持容器运行):
#!/bin/sh # 后台启动gunicorn,&表示让它在后台运行 gunicorn --bind :8000 --workers 3 --worker-class uvicorn.workers.UvicornWorker myapplication.asgi:application & # 前台运行task_process,作为容器的主进程 python manage.py task_process
注意:如果你的task_process本身是后台守护进程(运行后会自动退出到后台),那容器会因为这个进程退出而停止,这种情况需要修改task_process.py,让它保持前台运行(比如添加无限循环监听任务,或者禁用daemon化)。
生产环境推荐方案:用Supervisor管理多进程
如果是生产环境,更推荐用进程管理器来维护多个进程,避免后台进程意外退出无人监控。步骤如下:
- 修改Dockerfile,安装Supervisor:
# 假设你的基础镜像是python:3.x-slim RUN apt-get update && apt-get install -y supervisor && rm -rf /var/lib/apt/lists/* # 创建supervisor配置目录 RUN mkdir -p /var/log/supervisor # 复制supervisor配置文件 COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf # 替换原来的CMD CMD ["supervisord"]
- 在项目根目录创建
supervisord.conf文件:
[supervisord] nodaemon=true ; 让supervisor在前台运行,作为容器PID 1进程 [program:gunicorn] command=gunicorn --bind :8000 --workers 3 --worker-class uvicorn.workers.UvicornWorker myapplication.asgi:application directory=/app ; 替换成你的项目工作目录 stdout_logfile=/dev/stdout ; 把日志输出到容器stdout,方便docker logs查看 stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 autorestart=true ; 进程意外退出时自动重启 [program:task_process] command=python manage.py task_process directory=/app stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 autorestart=true
- 确保Dockerfile里设置了正确的工作目录:
WORKDIR /app
这样Supervisor会同时启动并监控gunicorn和task_process,任何一个进程挂掉都会自动重启,日志也会统一输出到容器日志中,方便排查问题。
内容的提问来源于stack exchange,提问作者Kaushik Bhave
相关产品推荐
相关产品推荐

