
1. 项目概述为什么选择Docker搭建开发环境在开发Python Web应用时最头疼的就是环境配置问题。不同项目可能依赖不同版本的Python、MySQL甚至Nginx的配置也各不相同。传统方式下我们不得不在本地安装各种软件配置环境变量处理依赖冲突——这简直就是开发者的噩梦。Docker的出现彻底改变了这种局面。通过容器化技术我们可以将Python运行环境、Nginx服务器和MySQL数据库打包成独立的容器每个项目都有自己完全隔离的环境。想象一下这样的场景你的同事刚接手项目时不再需要花两天时间配置环境只需一条docker-compose up命令就能获得和你完全一致的开发环境。我最近重构了一个老项目的开发环境用Docker整合了Python 3.9 Nginx 1.21 MySQL 8.0的组合。整个过程踩了不少坑但也积累了很多实战经验。下面就把这个完整的搭建过程记录下来包括那些官方文档里不会告诉你的细节。2. 环境准备与工具选型2.1 基础环境配置在开始之前确保你的系统已经安装以下组件Docker Engine 20.10社区版即可Docker Compose 1.29Git用于版本控制对于Windows/macOS用户建议直接安装Docker Desktop它包含了上述所有组件。Linux用户可以通过以下命令安装# Ubuntu示例 sudo apt-get update sudo apt-get install docker.io docker-compose git注意生产环境不建议使用root用户直接操作Docker。应该将当前用户加入docker组sudo usermod -aG docker $USER然后退出重新登录使配置生效2.2 为什么选择这些版本Python 3.9在3.8和3.10之间取得平衡既有新特性又足够稳定Nginx 1.21支持HTTP/2和更多现代Web特性MySQL 8.0相比5.7有显著的性能提升和JSON支持改进这些版本组合经过我的实际项目验证能够满足大多数Web应用的开发需求。当然你也可以根据项目需要调整版本号。3. 项目结构设计3.1 目录结构规划清晰的目录结构是项目可维护性的基础。这是我采用的目录布局project-root/ ├── docker-compose.yml # 容器编排主文件 ├── nginx/ │ ├── Dockerfile # Nginx自定义镜像配置 │ └── conf.d/ │ └── app.conf # Nginx站点配置 ├── mysql/ │ └── initdb.d/ # 初始化SQL脚本 ├── python/ │ ├── Dockerfile # Python应用镜像配置 │ ├── requirements.txt # Python依赖列表 │ └── app/ # 应用代码目录 └── .env # 环境变量配置这种结构将不同服务的配置分离同时保持整体项目的整洁。特别要注意的是MySQL的初始化脚本放在initdb.d目录下Docker会在容器首次启动时自动执行Nginx配置使用独立的app.conf文件避免直接修改主配置Python应用的依赖明确写在requirements.txt中3.2 Docker网络设计默认情况下Docker Compose会为所有服务创建共享网络。但为了更精细的控制我建议显式定义网络networks: frontend: driver: bridge backend: driver: bridge这样可以将Nginx放在frontend网络Python和MySQL放在backend网络既保证了必要的通信又增加了安全性。4. 容器化Python应用4.1 Python Dockerfile详解python/Dockerfile是构建Python应用镜像的核心。这是我使用的多阶段构建方案# 第一阶段构建环境 FROM python:3.9-slim as builder WORKDIR /app COPY requirements.txt . RUN pip install --user -r requirements.txt # 第二阶段运行环境 FROM python:3.9-slim WORKDIR /app ENV PATH/root/.local/bin:$PATH # 从builder阶段复制已安装的包 COPY --frombuilder /root/.local /root/.local COPY . . EXPOSE 8000 CMD [gunicorn, --bind, 0.0.0.0:8000, app.wsgi]这个配置有几个关键点使用多阶段构建减小最终镜像体积从~300MB降到~120MB将依赖安装与代码分离利用Docker层缓存加速重建使用Gunicorn作为WSGI服务器替代开发服务器经验在requirements.txt中固定版本号避免依赖冲突flask2.0.2 gunicorn20.1.0 mysql-connector-python8.0.264.2 处理Python应用配置在容器化环境中配置管理需要特别注意。我推荐使用环境变量配置文件结合的方式# app/config.py import os class Config: DB_HOST os.getenv(DB_HOST, localhost) DB_PORT os.getenv(DB_PORT, 3306) DB_USER os.getenv(DB_USER, root) DB_PASS os.getenv(DB_PASSWORD, ) DB_NAME os.getenv(DB_NAME, appdb)然后在docker-compose.yml中通过environment字段注入这些值。5. MySQL容器配置5.1 基础MySQL服务配置MySQL容器的配置相对简单但有些细节需要注意services: mysql: image: mysql:8.0 container_name: app_mysql environment: MYSQL_ROOT_PASSWORD: $DB_ROOT_PASSWORD MYSQL_DATABASE: $DB_NAME MYSQL_USER: $DB_USER MYSQL_PASSWORD: $DB_PASSWORD volumes: - mysql_data:/var/lib/mysql - ./mysql/initdb.d:/docker-entrypoint-initdb.d networks: - backend ports: - 3306:3306关键配置说明使用命名卷mysql_data持久化数据库文件initdb.d目录下的SQL文件会在首次启动时按字母顺序执行通过环境变量设置root密码从.env文件读取5.2 数据库初始化技巧在mysql/initdb.d/01-init.sql中可以放置DDL和基础数据CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- 插入测试数据 INSERT IGNORE INTO users (username, email) VALUES (admin, adminexample.com), (user1, user1example.com);重要MySQL 8.0默认使用caching_sha2_password认证如果Python连接有问题可以在初始化脚本中添加ALTER USER $DB_USER% IDENTIFIED WITH mysql_native_password BY $DB_PASSWORD;6. Nginx容器配置6.1 自定义Nginx镜像虽然可以直接使用官方Nginx镜像但自定义镜像能更好地适应我们的需求# nginx/Dockerfile FROM nginx:1.21-alpine # 删除默认配置 RUN rm /etc/nginx/conf.d/default.conf # 复制自定义配置 COPY conf.d/app.conf /etc/nginx/conf.d/ EXPOSE 80对应的Nginx配置nginx/conf.d/app.confupstream python_app { server python:8000; } server { listen 80; server_name localhost; location / { proxy_pass http://python_app; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /static/ { alias /app/static/; expires 30d; } }这个配置实现了将请求代理到Python应用正确处理静态文件保留原始客户端IP6.2 性能调优参数在高并发场景下可以调整Nginx的worker参数worker_processes auto; worker_connections 1024; keepalive_timeout 65; client_max_body_size 10m;这些值应该根据宿主机的CPU核心数和内存大小调整。7. Docker Compose整合7.1 完整的docker-compose.yml将所有服务整合在一起的完整配置version: 3.8 services: nginx: build: ./nginx ports: - 80:80 depends_on: - python networks: - frontend - backend python: build: ./python environment: - DB_HOSTmysql - DB_PORT3306 - DB_USER${DB_USER} - DB_PASSWORD${DB_PASSWORD} - DB_NAME${DB_NAME} volumes: - ./python/app:/app networks: - backend depends_on: - mysql mysql: image: mysql:8.0 environment: - MYSQL_ROOT_PASSWORD${DB_ROOT_PASSWORD} - MYSQL_DATABASE${DB_NAME} - MYSQL_USER${DB_USER} - MYSQL_PASSWORD${DB_PASSWORD} volumes: - mysql_data:/var/lib/mysql - ./mysql/initdb.d:/docker-entrypoint-initdb.d networks: - backend networks: frontend: backend: volumes: mysql_data:7.2 环境变量管理使用.env文件管理敏感信息# .env DB_ROOT_PASSWORDyour_strong_root_password DB_USERappuser DB_PASSWORDyour_app_db_password DB_NAMEappdb安全提示永远不要将.env文件提交到版本控制应该将其添加到.gitignore.env *.swp __pycache__8. 开发工作流优化8.1 热重载配置在开发阶段我们需要代码修改能立即生效。修改Python服务的配置python: build: ./python volumes: - ./python/app:/app environment: - FLASK_ENVdevelopment command: [gunicorn, --reload, --bind, 0.0.0.0:8000, app.wsgi]关键改动挂载应用代码卷实现实时同步添加--reload参数使Gunicorn监视文件变化设置FLASK_ENVdevelopment启用调试模式8.2 常用命令封装在项目根目录创建Makefile简化操作up: docker-compose up -d --build down: docker-compose down logs: docker-compose logs -f migrate: docker-compose exec python flask db upgrade test: docker-compose exec python pytest现在只需运行make up就能启动整个环境make logs查看日志非常方便。9. 常见问题排查9.1 MySQL连接问题如果Python应用无法连接MySQL检查确保MySQL容器完全启动可能需要30秒验证.env文件中的密码与MySQL配置一致检查网络配置确保Python和MySQL在同一个网络9.2 Nginx 502 Bad Gateway这通常表示Nginx无法连接到Python应用运行docker-compose ps确认Python容器正在运行检查Python应用是否监听正确的端口默认8000查看Python容器日志docker-compose logs python9.3 性能优化技巧当系统变慢时为MySQL添加查询缓存mysql: environment: - query_cache_size64M调整Gunicorn worker数量python: environment: - GUNICORN_WORKERS4为Nginx启用gzip压缩gzip on; gzip_types text/plain text/css application/json application/javascript;10. 生产环境准备10.1 安全加固措施准备上线时需要禁用调试模式FLASK_ENVproduction移除--reload参数限制MySQL root用户远程访问为Nginx配置SSL证书10.2 监控与日志添加基础监控services: prometheus: image: prom/prometheus ports: - 9090:9090 volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml配置日志轮转python: logging: driver: json-file options: max-size: 10m max-file: 311. 项目扩展思路这个基础环境可以进一步扩展添加Redis缓存层集成Celery异步任务队列配置CI/CD流水线加入Elasticsearch实现全文搜索每个扩展都可以作为独立的Docker服务加入现有架构这正是容器化的优势所在。12. 个人实战心得在实际项目中我总结了几个关键经验镜像标签管理始终为生产镜像打上语义化版本标签避免使用latest资源限制为每个容器设置内存和CPU限制防止单个服务耗尽资源备份策略定期备份MySQL数据卷可以使用cronjob自动执行开发效率在VS Code中安装Docker扩展可以直接在容器内开发最让我惊喜的是这套环境配置新项目时从零到运行只需不到10分钟。团队成员再也不用为在我机器上能运行的问题困扰真正实现了开发环境的一致性。