Docker 部署全流程:Dockerfile 与 Docker Compose 编排
📂 所属阶段:第六阶段 — 上线部署(生产篇)
🔗 相关章节:Gunicorn 与 Nginx · 环境变量与安全配置
本地开发一切顺利,一丢到服务器上就各种报错:Python 版本不对、PostgreSQL 连不上、Redis 没装、路径配置全乱……这种“环境不一致地狱”,几乎是每个 Flask 项目上线的必经之痛。
Docker 就是专治这类问题的良药——它把应用、依赖、运行时环境全部打包成一个标准化“镜像”,再通过镜像生成隔离的“容器”,无论在哪台机器上运行,容器内的环境都一模一样。这篇文章会带你从零开始,写出生产可用的 Dockerfile,再用 Docker Compose 编排 Flask + PostgreSQL + Redis + Nginx 的完整服务,并最终在云服务器上完成一键部署。
1. 写好一份高效安全的 Dockerfile
Dockerfile 是一份“镜像构建指南”,每一条指令都会生成一个镜像层。合理的分层顺序不仅可以大幅提升构建速度,还能提高安全性。我们将基于 Python 3.11 的轻量版镜像,一步步构建 Flask 应用。
完整 Dockerfile
分层思路拆解:
- 基础镜像:
python:3.11-slim对比完整版去掉了编译工具和文档,体积小,攻击面也更小。 - 依赖安装:利用
COPY requirements.txt .和RUN pip install ...形成独立的缓存层。日常修改应用代码不会触发依赖层重建,构建时间从几分钟缩短到几秒。 - 非 root 运行:默认容器内为 root 权限,一旦被攻破可能危及宿主机。切换到普通用户
appuser是最基本的安全实践。 - 启动命令:通过
gunicorn启动 Flask 应用工厂,适合生产环境多进程处理请求。
配套 requirements.txt
该文件列出了 Flask 全家桶以及常用的数据库驱动、异步任务库等,确保项目运行时所有依赖都齐备:
💡 小贴士:
psycopg2-binary是预编译版本,无需在容器内安装 PostgreSQL 开发库,非常适合 Docker 场景。
2. 用 Docker Compose 编排多容器
生产环境里,一个 Flask 应用往往还需要数据库、缓存、反向代理等多个服务。手动 docker run 挨个启动不仅繁琐,还很难管理依赖和网络。Docker Compose 让这一切只需要一个 YAML 文件,就能定义所有容器的构建方式、环境变量、数据卷、健康检查以及启动顺序。
2.1 本地开发版:热重载,快速调试
开发时我们需要:
- 修改代码后自动重载,无需重启容器;
- 环境变量可以直接写在 Compose 文件里,方便快速启动;
- 数据库和 Redis 有数据持久化,但允许随时清理。
关键设计点:
- 代码挂载:
volumes将本地的./app目录映射到容器内,任何代码改动都能即时刷新,无需重建镜像。 - 健康检查:
depends_on结合condition: service_healthy,确保数据库完全就绪后再启动 Web 服务,避免连接失败。 - 开发服务器:
command: flask run方便调试,但实际生产需要替换回 Gunicorn。
2.2 生产环境版:安全、稳定、持久化
生产部署与开发的最大区别在于:
- 使用预先构建好的镜像,而不是现场
build; - 环境变量单独放在
.env.production文件,绝不提交到代码仓库; - 所有容器开启
restart: always保证服务自愈; - 加入 Nginx 反向代理,处理静态文件、SSL 证书;
- 为关键服务配置健康检查。
生产配置要点:
restart: always:无论因为什么原因退出,Docker 都会自动重启容器,配合健康检查可快速恢复服务。- 敏感信息外置:
.env.production文件通常包含数据库密码、密钥等,通过.gitignore排除,杜绝泄露风险。 - 健康检查:Web 服务定期访问
/health接口(你需要在应用中简单实现该端点),确认服务处于正常状态。 - 数据持久化:数据库和 Redis 的数据都存储到命名卷中,即使容器被删除数据也不会丢失。
3. 一键构建与部署流程
本地开发
打开项目根目录,依次执行即可启动完整的开发环境:
云服务器生产部署
前提条件:服务器已安装 Docker 和 Docker Compose,项目根目录下存在 docker-compose.prod.yml、.env.production 以及 nginx/ 配置目录。
🚀 常用技巧:使用
--no-deps参数重启单个服务时,不会连带重启它依赖的数据库、Redis 等,从而实现零停机滚动更新。
4. 关键最佳实践回顾
- 分层缓存优化:Dockerfile 中将
COPY requirements.txt置于应用代码之前,充分利用层缓存,加快构建。 - 安全降权:容器内一律使用非 root 用户运行,缩小潜在攻击面。
- 数据持久化:数据库、Redis、静态文件、上传文件等全部挂载到 Docker 卷或主机目录,避免容器销毁时丢失数据。
- 健康检查全覆盖:生产环境为所有服务配置 healthcheck,确保依赖链可靠启动。
- 敏感信息隔离:生产环境变量、数据库密码等一律放在
.env.production文件,绝不随着代码一起提交。 - 轻量级镜像:基础镜像优先选择
-slim或-alpine版本,既能减小体积,又能降低安全风险。
🔗 扩展阅读
现在,你可以把这份配置直接应用到自己的 Flask 项目中,和“环境不一致”的麻烦彻底说再见。

