Flask 应用 Docker 容器化指南
用 Docker 与 Gunicorn 运行 Flask:项目结构、基础 Dockerfile、容器日志及 Docker Compose 开发配置,并说明非 root 用户和调试模式的边界。
直接回答:Flask 与 Docker 的组合在自建服务器和全托管平台之间提供了理想平衡点:容器比虚拟机轻量(共享宿主机内核),又能把应用与依赖打包成随处运行的整体——环境问题与部署事故大幅减少。
项目结构
flask-docker-app/
├── app.py
├── requirements.txt
├── Dockerfile
└── compose.yaml
app.py:
from flask import Flask, jsonify
app = Flask(__name__)
@app.get("/")
def index():
return jsonify(msg="Flask 容器版上线")
@app.get("/health")
def health():
return jsonify(status="ok")
编写 Dockerfile
开发用的 flask run 不适合生产,容器里用 Gunicorn:
FROM python:3.13-slim
ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
WORKDIR /code
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -r app
USER app
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "3", "app:app"]
requirements.txt 需包含 flask 和 gunicorn;生产锁定验证过的版本,.dockerignore 排除 .env、私钥和虚拟环境。绑定 0.0.0.0 是容器内服务对外可达的前提。
构建与运行
docker build -t flask-app .
docker run -d -p 127.0.0.1:8000:8000 --name web flask-app
curl http://localhost:8000/
容器日志
docker logs -f web
Flask 的 app.logger 输出到 stderr,Docker 自动捕获。先触发一次正常请求和一次异常,确认能看到请求标识、服务版本和堆栈;多副本排障时再按这些字段汇总日志。
Compose 开发环境
services:
web:
build: .
ports: ["127.0.0.1:8000:8000"]
volumes: [".:/code"]
environment:
FLASK_DEBUG: "1"
command: flask run --host 0.0.0.0 --port 8000 --debug
开发模式挂载源码 + debug 热重载;生产 compose 换回 Gunicorn 命令,关闭 debug,配置 TLS、鉴权、健康检查与资源限制;本示例只绑定本机,勿将开发调试端口暴露到公网。
常见问题(FAQ)
Q:Gunicorn workers 设多少?
A:经典起点 (2 × CPU 核数) + 1;容器里按 CPU limit 算。IO 密集应用可换 gevent worker 提高并发。
Q:Flask 的 debug 模式能带进生产吗?
A:绝对不能。debug 的交互式调试器等于远程代码执行后门,生产必须关闭。
Q:静态文件和用户上传怎么办?
A:静态文件让 Gunicorn 前面的反代(或 CDN)服务;上传文件存对象存储。容器文件系统是易失的,别放任何需要持久的东西。
官方参考
本文基于官方文档整理,未进行运行时或性能测试。示例中的业务函数、数据模型和部署地址需结合项目补全;局部片段不等同于完整生产应用。