1. 为什么选择DockerNginxGunicorn部署Django很多开发者第一次部署Django项目时往往会直接使用python manage.py runserver命令启动开发服务器。这种方式虽然简单但存在几个致命问题性能瓶颈开发服务器是单线程的并发能力极差实测在阿里云1核1G的ECS上QPS很难超过50安全隐患开发模式会暴露调试信息可能泄露敏感数据环境依赖服务器需要手动安装所有依赖容易产生在我机器上是好的这类问题我在早期部署项目时就遇到过因为服务器缺少某个系统库导致项目无法运行的尴尬情况。后来改用Docker容器化方案后这类问题再没出现过。DockerNginxGunicorn的组合完美解决了这些问题Docker将应用及其所有依赖打包成标准化单元实现一次构建到处运行GunicornPython WSGI HTTP服务器支持多worker进程轻松处理并发请求Nginx高性能Web服务器处理静态文件请求反向代理动态请求到Gunicorn2. 环境准备与项目配置2.1 阿里云ECS基础配置首先登录阿里云控制台购买ECS实例时建议选择操作系统Ubuntu 22.04 LTS实例规格至少1核2G个人博客2核4G更佳安全组开放80(HTTP)、443(HTTPS)、22(SSH)端口实例创建完成后通过SSH连接服务器ssh rootyour-server-ip更新系统软件包并安装基础工具apt update apt upgrade -y apt install -y git vim net-tools2.2 本地Django项目改造假设我们已有本地开发好的博客项目需要进行生产环境适配修改settings.py关键配置DEBUG False # 必须关闭调试模式 ALLOWED_HOSTS [your-domain.com, 服务器IP] STATIC_ROOT BASE_DIR / staticfiles # 静态文件收集目录生成依赖清单pip freeze requirements.txt测试Gunicorn能否正常运行gunicorn your_project.wsgi:application --bind 0.0.0.0:80003. Docker化Django应用3.1 编写Dockerfile在项目根目录创建Dockerfile# 使用官方Python镜像作为基础 FROM python:3.10-slim-bullseye # 设置工作目录 WORKDIR /app # 安装系统依赖 RUN apt-get update apt-get install -y \ gcc \ python3-dev \ rm -rf /var/lib/apt/lists/* # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制项目代码 COPY . . # 收集静态文件 RUN python manage.py collectstatic --noinput # 暴露端口 EXPOSE 8000 # 启动命令 CMD [gunicorn, your_project.wsgi:application, --bind, 0.0.0.0:8000]3.2 使用Docker Compose编排服务创建docker-compose.yml文件version: 3.8 services: web: build: . restart: always environment: - DJANGO_SECRET_KEYyour-secret-key - DJANGO_DEBUGFalse volumes: - static_volume:/app/staticfiles expose: - 8000 nginx: image: nginx:alpine ports: - 80:80 volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf - static_volume:/app/staticfiles:ro depends_on: - web volumes: static_volume:3.3 配置Nginx反向代理创建nginx/nginx.conf配置文件upstream django { server web:8000; } server { listen 80; server_name your-domain.com; location /static/ { alias /app/staticfiles/; expires 30d; } location / { proxy_pass http://django; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }4. 部署到阿里云ECS4.1 上传项目代码推荐使用Git管理代码git init git add . git commit -m Initial commit在服务器上克隆项目git clone https://github.com/yourname/your-project.git cd your-project4.2 构建并启动服务docker compose up -d --build检查服务状态docker compose ps docker compose logs -f4.3 常见问题排查静态文件404错误确认STATIC_ROOT设置正确检查Nginx配置中的alias路径是否与Docker卷挂载路径一致确保执行了collectstatic命令数据库连接问题如果使用MySQL/PostgreSQL确保数据库服务已启动检查settings.py中的数据库配置测试数据库连接python manage.py dbshellGunicorn worker崩溃适当增加worker数量--workers 4使用--timeout 120增加超时时间查看日志定位具体错误docker compose logs web5. 生产环境优化建议5.1 性能调优Gunicorn配置优化command: gunicorn your_project.wsgi:application --bind 0.0.0.0:8000 --workers 4 --threads 2 --worker-class gthread --max-requests 1000 --timeout 120Nginx优化配置# 在http块中添加 gzip on; gzip_types text/plain text/css application/json application/javascript; # 在server块中添加 client_max_body_size 20M; keepalive_timeout 65;5.2 安全加固使用HTTPS加密# 在nginx.conf中添加 listen 443 ssl; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem;限制管理后台访问# settings.py ADMIN_URL os.getenv(ADMIN_URL, custom-admin-path/)定期更新依赖docker compose build --no-cache5.3 监控与日志配置日志轮转# 在docker-compose.yml中添加 logging: driver: json-file options: max-size: 10m max-file: 3使用Supervisor管理进程可选[program:gunicorn] command/usr/local/bin/gunicorn your_project.wsgi:application --bind 0.0.0.0:8000 directory/app userroot autostarttrue autorestarttrue stderr_logfile/var/log/gunicorn.err.log stdout_logfile/var/log/gunicorn.out.log6. 持续集成与自动化部署6.1 GitHub Actions自动化创建.github/workflows/deploy.ymlname: Deploy to Aliyun ECS on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkoutv3 - name: Install SSH key uses: webfactory/ssh-agentv0.7.0 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - name: Deploy to server run: | ssh rootyour-server-ip cd /path/to/project git pull docker compose up -d --build6.2 备份策略数据库定期备份# 每天凌晨备份 0 0 * * * docker exec -t your-db-container pg_dump -U username dbname /backups/db-$(date \%Y\%m\%d).sql使用阿里云OSS存储备份# backup.py import oss2 from datetime import datetime auth oss2.Auth(your-access-key, your-secret-key) bucket oss2.Bucket(auth, your-endpoint, your-bucket-name) backup_file fdb-{datetime.now().strftime(%Y%m%d)}.sql bucket.put_object_from_file(backup_file, f/backups/{backup_file})7. 实际部署中的经验分享在多次项目部署中我总结出几个关键点容器资源限制在docker-compose.yml中为服务设置内存和CPU限制防止单个容器占用过多资源web: deploy: resources: limits: cpus: 1 memory: 1G环境变量管理敏感信息如数据库密码、API密钥等必须通过环境变量传递不要硬编码在配置文件中零停机部署使用Nginx的upstream模块实现蓝绿部署upstream django { server web:8000 max_fails3 fail_timeout30s; server web-backup:8000 backup; }健康检查为容器添加健康检查确保服务真正可用healthcheck: test: [CMD, curl, -f, http://localhost:8000/health/] interval: 30s timeout: 10s retries: 3多阶段构建优化Docker镜像大小# 构建阶段 FROM python:3.10 as builder RUN pip install --user -r requirements.txt # 运行阶段 FROM python:3.10-slim COPY --frombuilder /root/.local /root/.local遇到502 Bad Gateway错误时我通常会按照以下步骤排查检查Gunicorn是否正常运行docker compose exec web ps aux查看Nginx错误日志docker compose logs nginx测试端口连通性docker compose exec nginx curl -v http://web:8000检查防火墙设置ufw status