Docker容器中优雅停止Django开发服务器失败(退出码137)
解决Docker中Django容器
docker-compose stop后退出码137的问题 退出码137通常表示你的容器被强制终止(SIGKILL信号),而非优雅接收SIGTERM信号并关闭。虽然你已经遵循Docker建议使用了JSON格式的command,但核心问题出在python manage.py runserver进程本身——Django的开发服务器默认没有处理SIGTERM信号的逻辑,导致Docker在等待超时(默认10秒)后,不得不强制杀掉进程。
下面是几个可行的解决方案:
方案一:改用生产级WSGI服务器(推荐)
Django的runserver仅针对开发场景设计,并未实现优雅关闭逻辑。改用Gunicorn这类专业WSGI服务器可以完美解决问题,它原生支持SIGTERM信号,会优雅地停止worker进程。
- 在
requirements.txt中添加Gunicorn依赖:
gunicorn>=20.1.0
- 修改
docker-compose.yml中的command配置:
backend: build: . hostname: backend command: ["gunicorn", "--bind", "0.0.0.0:8000", "your_project_name.wsgi"] volumes: - .:/app
(请把your_project_name替换为你实际的Django项目名称,也就是包含wsgi.py的文件夹名)
方案二:为runserver添加信号处理脚本(适合坚持用开发服务器的场景)
如果你需要继续使用runserver,可以编写一个简单的启动脚本,负责捕获SIGTERM信号并转发给runserver进程,确保它能优雅关闭。
- 在项目根目录创建
start.sh脚本:
#!/bin/bash set -e # 后台启动Django开发服务器 python manage.py runserver 0.0.0.0:8000 & # 记录服务器进程PID SERVER_PID=$! # 定义信号处理函数:收到SIGTERM时转发给runserver handle_sigterm() { echo "Received SIGTERM, shutting down gracefully..." kill -TERM $SERVER_PID wait $SERVER_PID } # 注册SIGTERM信号的处理逻辑 trap handle_sigterm TERM # 等待服务器进程结束 wait $SERVER_PID
- 在Dockerfile中添加脚本执行权限:
# 已有的Docker指令... RUN chmod +x /app/start.sh
- 修改
docker-compose.yml中的command:
backend: build: . hostname: backend command: ["/app/start.sh"] volumes: - .:/app
额外排查点
退出码137也可能是容器内存不足导致OOM(内存耗尽)被系统强制杀掉。你可以通过docker stats命令查看容器运行时的内存占用情况,如果内存压力过大,可在docker-compose.yml中添加mem_limit配置调整容器内存配额。
内容的提问来源于stack exchange,提问作者aiven
相关产品推荐
相关产品推荐

