直接用 python app.py 启动模型服务在 Docker 中不靠谱,因其单线程、无进程管理、不响应 SIGTERM,易致容器崩溃;生产环境须用 Gunicorn 托管,配合 --preload、--workers 1、--timeout 120、--max-requests 1000 等参数保障稳定性。

为什么直接用 python app.py 启动模型服务在 Docker 里不靠谱
因为容器退出时主进程崩溃或没响应 SIGTERM,Kubernetes 或 docker-compose 就会反复重启失败容器。Python 自带的 Flask.run() 是单线程、无守护、不抗压的开发模式,没法处理并发请求、进程管理或优雅关闭。
Gunicorn 启动命令里哪些参数不能漏
默认 gunicorn app:app 对加载了 GB 级模型的进程就是定时炸弹——它不设超时、不限请求数、不 preload 模型,worker 还可能重复加载模型导致内存爆满。
-
--preload:让主进程加载模型后再 fork worker,避免每个 worker 单独 load -
--workers 1:ML 模型通常全局加载一次,多 worker 只会浪费内存 -
--timeout 120:防止长推理卡死整个 worker -
--max-requests 1000:强制轮换 worker,防内存泄漏累积
Dockerfile 分层和依赖安装怎么写才不翻车
镜像体积大、构建慢、缓存失效频繁,往往不是模型太大,而是 Dockerfile 写法错了。
- 基础镜像用
python:3.9-slim,别用ubuntu或完整版debian -
COPY requirements.txt .必须放在RUN pip install --no-cache-dir -r requirements.txt前,否则每次改代码都会重装依赖 - 把模型文件(
model.pt、tokenizer.json)放在COPY最后一步,避免它们一更新就废掉前面所有层缓存 - 运行时依赖(
gunicorn)、计算库(numpy)、模型专用包(transformers)分三类装,顺序不能乱
该用 ENTRYPOINT 还是 CMD 启动模型服务
CMD ["flask", "run"] 看似简单,但没法临时加参数,也没法做前置校验;而 ENTRYPOINT 能封装启动逻辑,又保留覆盖能力。
立即学习“Python免费学习笔记(深入)”;
- 写个
entrypoint.sh,检查/app/model.pt是否存在、GPU 是否可用、端口是否被占 -
exec "$@"是关键——它把CMD传进来的参数原样交给gunicorn,比如临时加--log-level debug -
ENTRYPOINT和CMD配合用:ENTRYPOINT ["/entrypoint.sh"]+CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]


















