Python Web应用Docker+Nginx部署实战指南

📅 2026/8/5 10:55:17
Python Web应用Docker+Nginx部署实战指南
1. Python Web应用部署方案概述在2023年的开发现场DockerNginx的组合已经成为Python Web应用部署的事实标准方案。这套方案之所以被广泛采用关键在于它完美解决了传统部署中的三个痛点环境不一致导致的在我机器上能跑问题、多应用端口管理混乱、以及HTTPS配置复杂。我最近刚用这套方案部署了一个Flask电商项目从测试环境到生产环境只用了不到15分钟。相比之前手动配环境、改配置的部署方式效率提升了至少10倍。下面我就结合这个实战案例拆解每个环节的技术细节和避坑要点。2. 环境准备与工具选型2.1 服务器基础配置推荐使用Ubuntu 22.04 LTS作为基础系统这是目前最稳定的生产环境选择。在阿里云/腾讯云购买实例时注意勾选自动安装Docker选项能省去后续安装步骤。最低配置建议CPU2核动态页面多的选4核内存4GBPython应用内存占用较高系统盘50GB SSDDocker镜像很占空间重要提示购买云服务器时一定要选择同一个地域的ECS和容器镜像服务否则拉取镜像会产生流量费用。我曾经因为跨地域拉镜像一天被扣了200多块。2.2 Docker环境配置安装完Docker后需要立即做三件事配置镜像加速国内直连Docker Hub慢到怀疑人生sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ] } EOF sudo systemctl daemon-reload sudo systemctl restart docker安装docker-composesudo curl -L https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose设置用户组避免每次sudosudo usermod -aG docker $USER newgrp docker # 立即生效2.3 Python项目结构调整你的项目目录应该调整为以下结构以Flask为例myapp/ ├── app/ # 应用代码 │ ├── __init__.py │ └── views.py ├── requirements.txt # 依赖文件 ├── Dockerfile # 生产环境镜像 ├── docker-compose.yml └── nginx/ ├── nginx.conf # 主配置 └── sites-enabled/ # 站点配置关键点requirements.txt必须精确指定版本号否则后续构建可能失败。建议生成时使用pip freeze | grep -v pkg-resources requirements.txt3. Docker镜像构建实战3.1 编写高效的Dockerfile多阶段构建是必须掌握的技巧能大幅减小最终镜像体积我做的电商项目从1.2GB瘦身到180MB# 构建阶段 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 # 从构建阶段拷贝已安装的包 COPY --frombuilder /root/.local /root/.local COPY . . # 确保脚本可执行 RUN chmod x ./start.sh ENV PATH/root/.local/bin:$PATH CMD [./start.sh]几个优化点使用slim版本基础镜像分离构建和运行环境设置PATH让python命令可用通过start.sh启动应用方便注入环境变量3.2 镜像构建的坑与技巧缓存利用构建时按依赖变更频率排序COPY指令把变动少的放前面。比如先COPY requirements.txt再COPY代码这样修改代码时不会重复安装依赖。国内加速在Dockerfile最前面添加ENV PIP_INDEX_URLhttps://pypi.tuna.tsinghua.edu.cn/simple镜像瘦身构建完成后运行以下命令清理无用层docker image prune --force --all4. Nginx配置精要4.1 反向代理配置这是最简可用的Nginx配置保存为nginx/sites-enabled/myapp.confserver { listen 80; server_name yourdomain.com; location / { proxy_pass http://web:5000; # 这里的web是compose中的服务名 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; # 静态文件直接由Nginx处理 expires 30d; } }4.2 HTTPS自动配置使用Lets Encrypt的certbot自动获取证书docker run -it --rm \ -v /etc/letsencrypt:/etc/letsencrypt \ -v /var/lib/letsencrypt:/var/lib/letsencrypt \ -p 80:80 \ certbot/certbot certonly --standalone -d yourdomain.com然后在nginx配置中添加listen 443 ssl; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;5. 终极部署方案docker-compose完整的docker-compose.yml示例version: 3.8 services: web: build: . ports: - 5000:5000 environment: - FLASK_ENVproduction restart: unless-stopped volumes: - ./app:/app # 开发时挂载代码实时更新 nginx: image: nginx:alpine ports: - 80:80 - 443:443 volumes: - ./nginx:/etc/nginx/conf.d - /etc/letsencrypt:/etc/letsencrypt depends_on: - web启动命令docker-compose up -d --build6. 运维监控与问题排查6.1 常用诊断命令查看实时日志docker-compose logs -f --tail100 web进入容器调试docker exec -it myapp_web_1 bash资源占用查看docker stats6.2 性能优化参数在docker-compose.yml中添加资源限制web: deploy: resources: limits: cpus: 2 memory: 1G reservations: memory: 512M6.3 备份与恢复完整备份命令docker-compose exec db pg_dump -U postgres mydb backup.sql # PostgreSQL示例7. 高级技巧与扩展方案7.1 蓝绿部署实践通过标签实现零停机更新docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --scale web3 --no-recreate docker-compose exec nginx nginx -s reload7.2 日志集中管理在compose文件中添加services: fluentd: image: fluent/fluentd volumes: - ./logs:/fluentd/log web: logging: driver: fluentd options: fluentd-address: localhost:24224 tag: myapp.web7.3 自动伸缩配置使用docker-swarm模式docker swarm init docker service create --name web --replicas 3 -p 5000:5000 myapp_web8. 踩坑记录与终极建议时区问题所有容器默认UTC时间必须在Dockerfile中添加ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone文件权限容器内用户权限与宿主机冲突时在docker-compose.yml中添加user: ${UID:-1000}:${GID:-1000}内存泄漏Python应用建议在启动命令前加CMD [gunicorn, --bind, 0.0.0.0:5000, --workers, 4, --threads, 2, app:app]最后分享一个监控脚本check_deploy.sh#!/bin/bash response$(curl -s -o /dev/null -w %{http_code} http://localhost/health) if [ $response ! 200 ]; then docker-compose restart web echo $(date) - 检测到服务异常已自动重启 /var/log/app_monitor.log fi