以下是一个完整的 Django 项目 Docker 部署方案,包括 Django 应用Nginx 反向代理Let's Encrypt HTTPS 支持,支持一键部署。我们使用 Docker Compose 管理容器和服务。


目录结构

确保你的项目结构如下(以项目名 myproject 为例):

myproject/
├── app/
│   ├── Dockerfile
│   ├── requirements.txt
│   ├── manage.py
│   ├── myproject/  # Django 项目代码
│       ├── settings.py
│       ├── urls.py
│       ├── wsgi.py
├── nginx/
│   ├── nginx.conf
├── docker-compose.yml
├── certbot/
│   ├── data/  # 存放证书文件
│   ├── www/   # Let's Encrypt 验证用文件

1. Django 应用的 Dockerfile

app/Dockerfile 中定义:

# 使用官方 Python 基础镜像
FROM python:3.10-slim

# 设置工作目录
WORKDIR /app

# 安装依赖包
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制 Django 项目代码
COPY . .

# 暴露运行端口
EXPOSE 8000

# 运行 Django 应用
CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]

2. Nginx 配置

nginx/nginx.conf 中定义:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    # Let's Encrypt 验证路径
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    # 重定向所有 HTTP 请求到 HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://app:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

3. Docker Compose 配置

在项目根目录下创建 docker-compose.yml

version: '3.9'

services:
  app:
    build:
      context: ./app
    container_name: django_app
    volumes:
      - static_volume:/app/static
    expose:
      - "8000"

  nginx:
    image: nginx:latest
    container_name: nginx
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - static_volume:/app/static
      - ./certbot/www:/var/www/certbot
      - ./certbot/data:/etc/letsencrypt
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - app

  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot/data:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do sleep 10; done'"

volumes:
  static_volume:

4. 安装 HTTPS 证书

运行以下命令获取 Let's Encrypt 证书:

docker-compose run certbot certonly --webroot \
  -w /var/www/certbot \
  -d yourdomain.com -d www.yourdomain.com

5. 自动续期证书

添加自动续期命令到 crontab

crontab -e

添加以下内容:

0 0 * * * docker-compose run certbot renew && docker-compose restart nginx

6. 配置静态文件

在 Django 项目中,修改 settings.py

STATIC_URL = '/static/'
STATIC_ROOT = '/app/static'

收集静态文件:

docker-compose run app python manage.py collectstatic

7. 一键启动

启动所有服务:

docker-compose up -d

访问 https://yourdomain.com,你的 Django 项目已经通过 Nginx 和 HTTPS 部署完成。


8. 问题排查

问题:证书验证失败

  • 检查域名是否指向正确的服务器 IP。
  • 确保 80 和 443 端口未被防火墙阻止。

问题:静态文件无法加载

  • 确保 STATIC_ROOT 配置正确。
  • 确认 nginx 配置中的 static_volume 映射正常。

这个方案适用于容器化生产环境,提供了一键部署能力,并通过 Docker Compose 高度集成 Django、Nginx 和 Certbot。