Django 部署 — 从开发到上线
🕐 预计用时:2-3 小时 | 🎯 目标:掌握 Gunicorn + Nginx 部署、Docker 容器化和静态文件收集
📖 今日目录
1. 开发 vs 生产环境
⚠️ 生产环境三大铁律:1. DEBUG = False(泄露源码和敏感信息)2. SECRET_KEY 用环境变量(不要写在代码里)3. 不要用 runserver(单线程,性能差,不安全)
2. 生产环境配置
# config/settings_prod.pyimport osfrom .settings_base import *DEBUG = FalseSECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')ALLOWED_HOSTS = os.environ.get('DJANGO_ALLOWED_HOSTS', '').split(',')# 生产数据库(PostgreSQL)DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('DB_NAME', 'mydb'), 'USER': os.environ.get('DB_USER', 'myuser'), 'PASSWORD': os.environ.get('DB_PASSWORD'), 'HOST': os.environ.get('DB_HOST', 'localhost'), 'PORT': os.environ.get('DB_PORT', '5432'), }}# 安全设置SECURE_BROWSER_XSS_FILTER = TrueSECURE_CONTENT_TYPE_NOSNIFF = TrueSESSION_COOKIE_SECURE = True # 仅 HTTPS 传输 CookieCSRF_COOKIE_SECURE = TrueSECURE_SSL_REDIRECT = True # HTTP 自动跳转 HTTPS# 静态文件STATIC_ROOT = BASE_DIR / 'staticfiles'STATIC_URL = '/static/'# 媒体文件MEDIA_ROOT = BASE_DIR / 'media'MEDIA_URL = '/media/'# 日志LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'file': { 'level': 'WARNING', 'class': 'logging.FileHandler', 'filename': BASE_DIR / 'logs/django.log', }, }, 'loggers': { 'django': { 'handlers': ['file'], 'level': 'WARNING', 'propagate': True, }, },}
3. Gunicorn WSGI 服务器
🦄 什么是 Gunicorn?
Gunicorn(Green Unicorn)是一个 Python WSGI HTTP 服务器——它才是生产环境真正运行你的 Django 应用的程序。
# 开发环境:# 浏览器 → Django runserver(单线程,不安全)# 生产环境:# 浏览器 → Nginx(静态文件 + 反向代理) → Gunicorn(运行 Django) → Django 应用
# 安装pip install gunicorn# 启动(基本)gunicorn mysite.wsgi:application# 默认监听 127.0.0.1:8000# 启动(推荐配置)gunicorn mysite.wsgi:application \ --bind 0.0.0.0:8000 \ --workers 4 \ --timeout 120 \ --access-logfile logs/access.log \ --error-logfile logs/error.log
📋 Gunicorn 参数
| | |
|---|
--bind | | 127.0.0.1:8000 |
--workers | | 2 × CPU + 1 |
--timeout | | 120 |
--worker-class | | sync |
--access-logfile | | logs/access.log |
--error-logfile | | logs/error.log |
💡 Workers 数量公式:workers = 2 × CPU核心数 + 1• 1 核服务器 → 3 workers• 2 核服务器 → 5 workers• 4 核服务器 → 9 workers每个 worker 大约占用 50-200MB 内存,注意内存限制。
4. Nginx 反向代理
🔧 Nginx 的角色
# Nginx 在最前面,做三件事:# 1. 处理静态文件(CSS/JS/图片)—— 直接返回,不经过 Django# 2. 反向代理 —— 把动态请求转发给 Gunicorn# 3. SSL 终止 —— 处理 HTTPS 加密/解密# 请求流程:# 客户端 → Nginx (443/HTTPS)# ├── 静态文件 → 直接返回# └── 动态请求 → Gunicorn (8000) → Django
# /etc/nginx/sites-available/mysiteserver { listen 80; server_name yourdomain.com; return 301 https://$server_name$request_uri;}server { listen 443 ssl; server_name yourdomain.com; # SSL 证书 ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; # 最大上传大小 client_max_body_size 10M; # 静态文件(Nginx 直接处理,不经过 Django) location /static/ { alias /path/to/mysite/staticfiles/; expires 30d; } location /media/ { alias /path/to/mysite/media/; expires 30d; } # 动态请求转发给 Gunicorn location / { proxy_pass http://127.0.0.1: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; proxy_set_header X-Forwarded-Proto $scheme; }}
# 启用站点sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/sudo nginx -t # 测试配置sudo systemctl reload nginx
5. 静态文件收集
# Django 的静态文件分散在各个 app 的 static/ 目录中# collectstatic 把它们全部收集到 STATIC_ROOT 目录# settings.pySTATIC_ROOT = BASE_DIR / 'staticfiles'STATIC_URL = '/static/'# 执行收集python manage.py collectstatic# 会把所有 app 的 static/ 文件复制到 staticfiles/ 目录# Nginx 配置 alias 指向这个目录
💡 为什么要 collectstatic?Django 的开发服务器可以自动找到各 app 的静态文件,但生产环境中 Nginx 不知道 Django 的目录结构。collectstatic 把所有静态文件集中到一个目录,Nginx 直接从那里提供服务。
6. Docker 容器化
🐳 Dockerfile
# DockerfileFROM python:3.12-slim# 设置工作目录WORKDIR /app# 安装系统依赖RUN apt-get update && apt-get install -y \ gcc \ libpq-dev \ && rm -rf /var/lib/apt/lists/*# 安装 Python 依赖COPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txt# 复制项目代码COPY . .# 收集静态文件RUN python manage.py collectstatic --noinput# 暴露端口EXPOSE 8000# 启动 GunicornCMD ["gunicorn", "mysite.wsgi:application", \ "--bind", "0.0.0.0:8000", \ "--workers", "3"]
# requirements.txtdjango==5.1djangorestframework==3.15.2gunicorn==23.0.0psycopg2-binary==2.9.9whitenoise==6.7.0 # 静态文件服务(不需要 Nginx 时)python-dotenv==1.0.1 # 读取 .env 文件
🏗️ 构建与运行
# 构建镜像docker build -t mysite .# 运行容器docker run -d \ -p 8000:8000 \ -e DJANGO_SECRET_KEY='your-secret-key' \ -e DB_NAME=mydb \ -e DB_USER=myuser \ -e DB_PASSWORD=mypass \ -e DB_HOST=host.docker.internal \ --name mysite \ mysite# 查看日志docker logs -f mysite
7. Docker Compose
当你的应用有多个服务(Django + PostgreSQL + Redis + Nginx),用 Docker Compose 编排它们。
# docker-compose.ymlversion: '3.8'services: db: image: postgres:16 environment: POSTGRES_DB: mydb POSTGRES_USER: myuser POSTGRES_PASSWORD: mypass volumes: - postgres_data:/var/lib/postgresql/data ports: - "5432:5432" web: build: . command: gunicorn mysite.wsgi:application --bind 0.0.0.0:8000 --workers 3 environment: - DJANGO_SECRET_KEY=your-secret-key - DB_NAME=mydb - DB_USER=myuser - DB_PASSWORD=mypass - DB_HOST=db volumes: - static_files:/app/staticfiles - media_files:/app/media depends_on: - db ports: - "8000:8000" nginx: image: nginx:alpine volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf - static_files:/usr/share/nginx/html/static - media_files:/usr/share/nginx/html/media ports: - "80:80" - "443:443" depends_on: - webvolumes: postgres_data: static_files: media_files:
# 启动所有服务docker-compose up -d# 查看状态docker-compose ps# 查看日志docker-compose logs -f web# 停止docker-compose down
💡 Docker Compose 一键部署:docker-compose up -d 一条命令启动:• PostgreSQL 数据库• Django 应用(Gunicorn)• Nginx 反向代理不用手动安装任何依赖,不用配置系统环境。换一台服务器?docker-compose up -d 就行。
8. 部署清单
| | |
|---|
| | export DJANGO_SECRET_KEY=... |
| | DEBUG = False |
| | ALLOWED_HOSTS = ['yourdomain.com'] |
| | python manage.py collectstatic |
| | python manage.py migrate |
| | python manage.py createsuperuser |
| | gunicorn mysite.wsgi:application |
| | 编辑 /etc/nginx/sites-available/ |
| | certbot --nginx -d yourdomain.com |
| | 访问 https://yourdomain.com |
💡 免 Nginx 方案:WhiteNoise如果不想配置 Nginx,可以用 whitenoise 让 Gunicorn 直接提供静态文件:pip install whitenoise# settings.py 中间件添加:MIDDLEWARE = ['whitenoise.middleware.WhiteNoiseMiddleware', ...]适合小型项目,大型项目还是推荐 Nginx。
9. 今日练习
🏋️ 练习 1:生产配置
# 创建 settings_prod.py:# - DEBUG = False# - SECRET_KEY 从环境变量读取# - ALLOWED_HOSTS 从环境变量读取# - 配置 PostgreSQL 数据库# - 配置日志系统
🏋️ 练习 2:Docker 化
# 为 Django 项目创建:# 1. Dockerfile# 2. requirements.txt# 3. docker-compose.yml(Django + PostgreSQL)# 4. 构建并运行
🏋️ 练习 3:Gunicorn + Nginx
# 在服务器上部署:# 1. 用 Gunicorn 启动 Django# 2. 配置 Nginx 反向代理# 3. 配置 SSL 证书# 4. 测试访问
10. 今日小结
| |
|---|
| DEBUG=False、SECRET_KEY 环境变量、ALLOWED_HOSTS |
| |
| |
| |
| |
| 多服务编排:Django + PostgreSQL + Nginx |
| |
🚀 明日预告:Day 66 — 在线商城综合项目Django 全套学完了!明天把所有知识合体——做一个完整的在线商城 MVP:商品展示、购物车、订单系统、用户中心。这是 Django 阶段的终极实战,也是你从"学习者"到"开发者"的关键一步!