如何将Python Flask应用打包成Docker镜像_编写Dockerfile脚本
Flask应用打包前必须确认的三个路径:app.py须置于根目录以避免ModuleNotFoundError;requirements.txt须与Dockerfile同目录或显式指定路径;import路径须适配容器内结构,确保config.py等依赖文件被正确COPY且不在被忽略目录中。
Flask应用打包前必须确认的三个路径
你的 app.py(或主入口文件)不能藏在子目录里,Docker 构建时默认工作目录是镜像根目录,python app.py 会直接报 ModuleNotFoundError。常见错误是项目结构为 src/app.py 或 myproject/app.py,却没在 Dockerfile 中 COPY 到正确位置或没用 WORKDIR 切换。
务必检查并统一以下三点:
-
requirements.txt必须和Dockerfile在同一目录(或显式指定相对路径),否则COPY requirements.txt .会失败 -
app.py的 import 路径要适配容器内结构——比如用了from config import Config,就得确保config.py也被COPY进来,且不在__pycache__或.git目录中(默认.dockerignore应排除它们) - 如果用了
flask run启动,注意它默认绑定127.0.0.1:5000,容器内必须改用--host=0.0.0.0,否则外部访问不到
Dockerfile 中最易写错的 FROM 和 CMD 组合
别用 FROM python:3.11-slim 然后直接 CMD ["flask", "run"] ——这会因缺少 FLASK_APP 环境变量而报 Failed to find Flask application or factory in module。更稳妥的是显式指定启动命令和环境。
推荐写法(兼顾可读与健壮):
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 5000 ENV FLASK_APP=app.py ENV FLASK_ENV=production CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]
说明:
- 用
gunicorn替代flask run是生产必需——后者是开发服务器,不支持多进程、无健康检查、无法优雅重启 -
FLASK_ENV=production关闭调试模式,避免暴露代码和交互式调试器(debug=True在容器里绝对禁用) -
CMD中的app:app表示模块名app(即app.py)里的 Flask 实例变量名app;若你定义的是application = Flask(...),就得写成app:application
构建时 pip install 失败的常见原因和绕过方式
本地 pip install -r requirements.txt 成功,但 Docker 构建时卡在某个包(如 psycopg2、numpy)编译失败,大概率是基础镜像缺系统依赖。
Python 3.14.3
微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。
典型报错片段:error: command 'gcc' failed with exit status 1 或 pg_config executable not found。
解决路径分两种:
- 换预编译镜像:用
FROM python:3.11-slim-bookworm(Debian 12)比alpine兼容性更好;或直接上FROM tiangolo/meeting:python3.11(含常用 C 依赖) - 手动装依赖:在
RUN pip install前加RUN apt-get update && apt-get install -y build-essential libpq-dev gcc(Debian/Ubuntu 系),注意最后加&& rm -rf /var/lib/apt/lists/*减小镜像体积 - 对纯 Python 包,加
--only-binary=all强制用 wheel:pip install --only-binary=all -r requirements.txt
运行容器后无法访问 5000 端口的排查顺序
执行 docker run -p 5000:5000 my-flask-app 后浏览器打不开,先别急着改代码——90% 是网络绑定或端口映射问题。
按顺序检查:
- 容器是否真在运行:
docker ps看 STATUS 是否为Up X seconds,不是一闪而逝(那说明CMD启动失败,立刻docker logs) - 日志里有没有
Booting worker with pid(gunicorn)或* Running on http://0.0.0.0:5000(flask run)——没有就说明启动命令没生效 - 确认
EXPOSE 5000只是文档声明,真正映射靠docker run -p;如果用了-p 8080:5000,那得访问localhost:8080 - Flask 代码里是否写了
app.run(host='127.0.0.1')?必须删掉或改成host='0.0.0.0',否则只监听本地回环
最常被忽略的是:用 VS Code Dev Container 或某些 IDE 插件启动时,它可能自动加了 --network=host 或覆盖了 -p 参数,此时要看实际执行的 docker run 命令全貌。