Flask 笔记十七:Docker 打包 Flask 应用

📅 2026/6/27 19:28:53
Flask 笔记十七:Docker 打包 Flask 应用
上一篇我们用 pytest 给路由和 API 加了自动化测试。第十四篇是在服务器上 手动装 Python、配 venv、起 Gunicorn——能跑但换一台机器往往又要重来一遍。这一篇做一件事用 Docker 把「应用 运行环境」打成一个镜像再用 docker-compose 一键拉起 Flask 和 MySQL。例子仍是通用的Note备忘录项目不涉及任何真实业务。1. 学完后你能做什么写Dockerfile用 Gunicorn 启动 Flask写docker-compose.ymlFlask MySQL 一起跑用 环境变量 传配置接第十二篇知道 卷volume 持久化数据库本地一条命令docker compose up复现「接近生产」的环境2. Docker 解决什么问题没有 Docker有 Docker「我机器上能跑啊」镜像里环境一致Python 版本、系统包装一堆镜像自带依赖新人搭环境半天docker compose up生产和本地差一截同一套镜像可部署Docker 不是必须小项目直接 Gunicorn 也完全可以。团队变大、要 CI/CD、要多环境一致时Docker 很省心。3. 整体架构docker compose up│├── 容器 webFlask Gunicorn :5000│ ││ └── 连 → db:3306│└── 容器 dbMySQL 8└── volume 持久化数据浏览器访问http://127.0.0.1:5000映射到 web 容器。4. 项目里要加哪些文件myproject/├── app/├── manage.py├── requirements.txt├── Dockerfile # 新增├── docker-compose.yml # 新增├── .dockerignore # 新增减小镜像└── .env.docker # 可选compose 读环境变量5. DockerfileWeb 镜像FROM python:3.11-slimWORKDIR /app# 系统依赖MySQL 客户端库等按需RUN apt-get update apt-get install -y --no-install-recommends \gcc default-libmysqlclient-dev pkg-config \ rm -rf /var/lib/apt/lists/*COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt gunicornCOPY . .ENV FLASK_APPappENV PYTHONUNBUFFERED1EXPOSE 5000CMD [gunicorn, -w, 2, -b, 0.0.0.0:5000, app:app]说明python:3.11-slim体积小够用先 COPY requirements 再 COPY 代码改代码时重建层更快CMD gunicorn接第十四篇不用app.run()worker 容器里 2 个 即可别贪多若只用 SQLite、不连 MySQL可去掉gcc、mysqlclient相关 apt 包。6..dockerignore避免把垃圾打进镜像.venv__pycache__*.pyc.git.pytest_cacheinstance/*.db.env*.mdtests/7. docker-compose.ymlservices:db:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: rootpassMYSQL_DATABASE: notesMYSQL_USER: notesMYSQL_PASSWORD: notespassvolumes:- mysql_data:/var/lib/mysqlports:- 3306:3306healthcheck:test: [CMD, mysqladmin, ping, -h, localhost]interval: 5stimeout: 5sretries: 10web:build: .ports:- 5000:5000environment:FLASK_DEBUG: 0SECRET_KEY: change-me-in-productionDATABASE_URL: mysqlpymysql://notes:notespassdb:3306/notesdepends_on:db:condition: service_healthycommand: sh -c flask db upgrade gunicorn -w 2 -b 0.0.0.0:5000 app:appvolumes:mysql_data:要点服务名db→ Web 容器里主机名就是db不是127.0.0.1depends_on healthcheck等 MySQL 就绪再起 Flaskcommand里先flask db upgrade接第十五篇再起 Gunicornmysql_datavolume删容器数据还在app/__init__.py需能读DATABASE_URL第十二篇环境变量那套。8. 启动与常用命令# 构建并后台启动docker compose up -d --build# 看日志docker compose logs -f web# 进 web 容器执行 CLIdocker compose exec web flask create-admin admin# 停掉docker compose down# 停掉并删数据库卷慎用docker compose down -v浏览器打开http://127.0.0.1:5000。9. 环境变量怎么管理不要把真密码写进 Dockerfile 提交 Git。方式用法docker-compose.yml的environment本地演示可以生产换 secrets.env文件compose 自动读SECRET_KEYxxx一行一个服务器上export compose生产常见.env示例加入.gitignoreSECRET_KEY本地随机长字符串MYSQL_PASSWORDnotespassdocker-compose.yml里可写environment:SECRET_KEY: ${SECRET_KEY}DATABASE_URL: mysqlpymysql://notes:${MYSQL_PASSWORD}db:3306/notes10. 开发时代码热更新可选生产镜像不必挂载源码本地开发可挂载目录改代码重启容器即生效web:build: .volumes:- .:/appenvironment:FLASK_DEBUG: 1command: flask run --host0.0.0.0 --port5000注意FLASK_DEBUG1只限本地 Docker 开发生产 compose 仍用 Gunicorn FLASK_DEBUG0。很多人 开发仍用本机 venv flask runDocker 只用来测「和生产一致」的集成——这样也行。11. 和前面各篇怎么串起来篇在 Docker 里十二 环境变量environment/.env十四 GunicornCMD或 composecommand十五 CLIdocker compose exec web flask ...十六 pytestCI 里docker compose run web pytest可选七 Migrate启动前flask db upgrade12. 流程示意docker compose up --build│▼构建 web 镜像pip install COPY 代码│▼启动 dbMySQL volume│▼db healthcheck 通过│▼webflask db upgrade → gunicorn│▼http://127.0.0.1:5000 可访问13. 新手常踩的 6 个坑Web 连127.0.0.1:3306— 在容器里 127.0.0.1 是自己MySQL 要用主机名db。没等 MySQL 就绪就 migrate — 用healthcheckdepends_on。把.env提交 Git — 进.gitignore。镜像里用app.run(debugTrue)— 生产用 Gunicorn。不设 volume — 容器删了数据库没了。镜像巨大 — 用.dockerignore、多阶段构建进阶再学。14. 小结记住五件事Dockerfile装依赖 gunicorn app:appdocker-compose.ymlweb db volume数据库主机名用服务名db启动前flask db upgrade密钥走环境变量别写进镜像十七篇下来你已经会本机开发 → 测试 → Gunicorn 部署 → CLI 运维 → Docker 一键环境。