从零到一:基于Docker容器化与Nginx+Gunicorn在阿里云ECS部署Django博客(实战篇)

📅 2026/7/14 1:45:32 👁️ 阅读次数 📝 编程学习
从零到一:基于Docker容器化与Nginx+Gunicorn在阿里云ECS部署Django博客(实战篇)

1. 为什么选择Docker+Nginx+Gunicorn部署Django?

很多开发者第一次部署Django项目时,往往会直接使用python manage.py runserver命令启动开发服务器。这种方式虽然简单,但存在几个致命问题:

  • 性能瓶颈:开发服务器是单线程的,并发能力极差,实测在阿里云1核1G的ECS上,QPS很难超过50
  • 安全隐患:开发模式会暴露调试信息,可能泄露敏感数据
  • 环境依赖:服务器需要手动安装所有依赖,容易产生"在我机器上是好的"这类问题

我在早期部署项目时,就遇到过因为服务器缺少某个系统库导致项目无法运行的尴尬情况。后来改用Docker容器化方案后,这类问题再没出现过。

Docker+Nginx+Gunicorn的组合完美解决了这些问题:

  • Docker:将应用及其所有依赖打包成标准化单元,实现"一次构建,到处运行"
  • Gunicorn:Python WSGI HTTP服务器,支持多worker进程,轻松处理并发请求
  • Nginx:高性能Web服务器,处理静态文件请求,反向代理动态请求到Gunicorn

2. 环境准备与项目配置

2.1 阿里云ECS基础配置

首先登录阿里云控制台,购买ECS实例时建议选择:

  • 操作系统:Ubuntu 22.04 LTS
  • 实例规格:至少1核2G(个人博客2核4G更佳)
  • 安全组:开放80(HTTP)、443(HTTPS)、22(SSH)端口

实例创建完成后,通过SSH连接服务器:

ssh root@your-server-ip

更新系统软件包并安装基础工具:

apt update && apt upgrade -y apt install -y git vim net-tools

2.2 本地Django项目改造

假设我们已有本地开发好的博客项目,需要进行生产环境适配:

  1. 修改settings.py关键配置:
DEBUG = False # 必须关闭调试模式 ALLOWED_HOSTS = ['your-domain.com', '服务器IP'] STATIC_ROOT = BASE_DIR / 'staticfiles' # 静态文件收集目录
  1. 生成依赖清单:
pip freeze > requirements.txt
  1. 测试Gunicorn能否正常运行:
gunicorn your_project.wsgi:application --bind 0.0.0.0:8000

3. 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_KEY=your-secret-key - DJANGO_DEBUG=False 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. 部署到阿里云ECS

4.1 上传项目代码

推荐使用Git管理代码:

git init git add . git commit -m "Initial commit"

在服务器上克隆项目:

git clone https://github.com/yourname/your-project.git cd your-project

4.2 构建并启动服务

docker compose up -d --build

检查服务状态:

docker compose ps docker compose logs -f

4.3 常见问题排查

  1. 静态文件404错误

    • 确认STATIC_ROOT设置正确
    • 检查Nginx配置中的alias路径是否与Docker卷挂载路径一致
    • 确保执行了collectstatic命令
  2. 数据库连接问题

    • 如果使用MySQL/PostgreSQL,确保数据库服务已启动
    • 检查settings.py中的数据库配置
    • 测试数据库连接:python manage.py dbshell
  3. Gunicorn worker崩溃

    • 适当增加worker数量:--workers 4
    • 使用--timeout 120增加超时时间
    • 查看日志定位具体错误:docker compose logs web

5. 生产环境优化建议

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 120

Nginx优化配置:

# 在http块中添加 gzip on; gzip_types text/plain text/css application/json application/javascript; # 在server块中添加 client_max_body_size 20M; keepalive_timeout 65;

5.2 安全加固

  1. 使用HTTPS加密:

    # 在nginx.conf中添加 listen 443 ssl; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem;
  2. 限制管理后台访问:

    # settings.py ADMIN_URL = os.getenv('ADMIN_URL', 'custom-admin-path/')
  3. 定期更新依赖:

    docker compose build --no-cache

5.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 user=root autostart=true autorestart=true stderr_logfile=/var/log/gunicorn.err.log stdout_logfile=/var/log/gunicorn.out.log

6. 持续集成与自动化部署

6.1 GitHub Actions自动化

创建.github/workflows/deploy.yml

name: Deploy to Aliyun ECS on: push: branches: [ main ] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Install SSH key uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - name: Deploy to server run: | ssh root@your-server-ip "cd /path/to/project && git pull && docker compose up -d --build"

6.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 = f'db-{datetime.now().strftime("%Y%m%d")}.sql' bucket.put_object_from_file(backup_file, f'/backups/{backup_file}')

7. 实际部署中的经验分享

在多次项目部署中,我总结出几个关键点:

  1. 容器资源限制:在docker-compose.yml中为服务设置内存和CPU限制,防止单个容器占用过多资源

    web: deploy: resources: limits: cpus: '1' memory: 1G
  2. 环境变量管理:敏感信息如数据库密码、API密钥等必须通过环境变量传递,不要硬编码在配置文件中

  3. 零停机部署:使用Nginx的upstream模块实现蓝绿部署

    upstream django { server web:8000 max_fails=3 fail_timeout=30s; server web-backup:8000 backup; }
  4. 健康检查:为容器添加健康检查,确保服务真正可用

    healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health/"] interval: 30s timeout: 10s retries: 3
  5. 多阶段构建:优化Docker镜像大小

    # 构建阶段 FROM python:3.10 as builder RUN pip install --user -r requirements.txt # 运行阶段 FROM python:3.10-slim COPY --from=builder /root/.local /root/.local

遇到502 Bad Gateway错误时,我通常会按照以下步骤排查:

  1. 检查Gunicorn是否正常运行:docker compose exec web ps aux
  2. 查看Nginx错误日志:docker compose logs nginx
  3. 测试端口连通性:docker compose exec nginx curl -v http://web:8000
  4. 检查防火墙设置:ufw status