摘要:Django + Gunicorn + Nginx 是部署 Python Web 应用(特别是 Django)的一个经典、高效且可靠的生产级架构。这条部署之路清晰地将各组件职责分离,充分利用各自的优势。下面我们来浅谈这条路径的关键环节和最佳实践:(示意图:用户
Django + Gunicorn + Nginx 是部署 Python Web 应用(特别是 Django)的一个经典、高效且可靠的生产级架构。这条部署之路清晰地将各组件职责分离,充分利用各自的优势。下面我们来浅谈这条路径的关键环节和最佳实践:
(示意图:用户请求 -> Nginx -> Gunicorn -> Django App)
核心组件分工
Django:Ø 角色: Web 应用核心框架。
Ø 职责: 处理业务逻辑、数据库交互(ORM)、模板渲染、路由分发、表单处理、用户认证等。它专注于生成动态内容。
Ø 关键生产设置:
DEBUG = False (绝对必须!)
正确配置 ALLOWED_HOSTS (包含你的域名/IP)
设置 SECRET_KEY 安全(通过环境变量!)
配置好数据库连接 (DATABASES)
收集静态文件 (python manage.py collectstatic)
考虑使用 .env 文件或环境变量管理敏感配置。
Gunicorn (Green Unicorn):
Ø 角色: WSGI HTTP Server。
Ø 职责: 作为 Django 应用和外部世界(Nginx)之间的桥梁。
启动 Django: 加载你的 Django 应用实例。
处理并发请求: 使用 worker 进程(同步或异步 worker 如 gevent/eventlet)处理来自 Nginx 的请求。管理 worker 的生命周期(启动、重启崩溃的 worker)。
WSGI 协议: 遵循 Python WSGI 规范,与 Django 通信。
基础性能: 提供基本的请求处理能力和并发支持。
关键优势: 简单、稳定、高效、纯 Python,对 Django 支持极佳。
Nginx:Ø 角色: 高性能 Web 服务器 / 反向代理 / 负载均衡器。
Ø 职责:
反向代理: 接收所有来自客户端的 HTTP(S) 请求,并将其反向代理到后端的 Gunicorn 进程(通常在 localhost:8000 或 Unix socket)。客户端只与 Nginx 通信,不知道 Gunicorn/Django 的存在。
处理静态文件: 直接高效地提供 CSS、JavaScript、图片等静态文件(由 collectstatic 收集)。这比让 Django 或 Gunicorn 处理静态文件快几个数量级。
处理媒体文件: 通常也直接提供用户上传的文件(如果存储在服务器本地)。
SSL/TLS 终止: 处理 HTTPS 加密解密,减轻后端 Gunicorn/Django 的负担。
缓冲和缓存: 缓冲客户端请求和上游响应,提高性能。可配置缓存静态内容甚至部分动态内容。
负载均衡(可选): 如果运行多个 Gunicorn 实例(在多核机器上很常见),Nginx 可以将请求分发到它们。
基础安全: 提供限速、基本访问控制、抵御某些 DDoS 攻击的能力。
处理慢客户端: 防止慢速客户端拖慢后端应用服务器。
部署之路:关键步骤
准备服务器环境:Ø 选择 Linux 发行版 (Ubuntu, Debian, CentOS 等)。
Ø 更新系统,安装必要的系统依赖 (Python 3, pip, build-essentials, 数据库客户端库等)。
Ø 创建专用系统用户运行应用(增强安全)。
Ø 配置防火墙 (如 ufw),开放 SSH、HTTP(80)、HTTPS(443) 端口。
部署 Django 项目代码:Ø 将代码安全地传输到服务器 (Git, SCP, Rsync, CI/CD 管道)。
Ø 创建 Python 虚拟环境 (python -m venv myenv),激活它 (source myenv/bin/activate)。
Ø 在虚拟环境中安装项目依赖 (pip install -r requirements.txt),务必包含 gunicorn。
Ø 配置生产环境设置 (.env, 环境变量, 或 settings_prod.py + DJANGO_SETTINGS_MODULE)。
Ø 运行数据库迁移 (python manage.py migrate)。
Ø 收集静态文件 (python manage.py collectstatic - 指定 STATIC_ROOT 目录,通常是 Nginx 能访问的地方)。
配置和启动 Gunicorn:Ø 测试运行: 在项目目录下:gunicorn myproject.wsgi:application。这会启动一个 worker 进程监听 127.0.0.1:8000。确保 Django 应用能正常响应。
Ø 创建 Gunicorn 配置文件 (gunicorn_config.py 或类似): 使配置更清晰可管理。
python
# gunicorn_config.py
bind = "unix:/run/gunicorn.sock" # 或 "127.0.0.1:8000" (推荐用 Unix socket 更高效安全)
workers = (2 * cpu_count) + 1 # 常见公式,根据 CPU 核心数调整
worker_class = "sync" # 或 "gevent"/"eventlet" (需要额外安装,适合 I/O 密集型)
worker_tmp_dir = "/dev/shm" # 如果/tmp不在内存中,可提升性能
timeout = 120 # 防止worker被长时间请求卡死
keepalive = 5 # 优化连接
accesslog = "-" # 输出到 stdout (方便journalctl查看)
errorlog = "-" # 输出到 stderr
# user = "myprojectuser" # 如果用systemd服务启动,通常在服务文件里指定User
# group = "myprojectgroup"
# chdir = "/path/to/your/project" # 工作目录
# module = "myproject.wsgi:application"
Ø 创建 Systemd 服务文件 (/etc/systemd/system/gunicorn.service): 让 Gunicorn 作为守护进程运行,开机自启,崩溃自动重启。
systemd
[Unit]
Description=gunicorn daemon for myproject
After=network.target
[Service]
User=myprojectuser # 专用用户
Group=www-data # 或 myprojectgroup, 确保和Nginx能访问socket
WorkingDirectory=/path/to/your/project
ExecStart=/path/to/venv/bin/gunicorn --config /path/to/gunicorn_config.py myproject.wsgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.target
Ø 启动并启用服务:
bash
sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl enable gunicorn
sudo systemctl status gunicorn # 检查状态和日志
journalctl -u gunicorn.service -f # 跟踪日志
Ø 确保 /run/gunicorn.sock (或配置的路径) 被创建,且 Nginx 用户有读写权限。
配置和启动 Nginx:Ø 安装 Nginx:sudo apt install nginx (Ubuntu/Debian)。
Ø 创建站点配置文件 (/etc/nginx/sites-available/myproject):
nginx
server {
listen 80;
server_name yourdomain.com www.yourdomain.com; # 或服务器IP地址
# 重定向 HTTP 到 HTTPS (如果启用HTTPS)
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# SSL 配置 (使用 Let's Encrypt certbot 自动获取)
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem;
# ... 其他SSL优化配置 (如协议、加密套件) ...
# 日志
access_log /var/log/nginx/myproject.access.log;
error_log /var/log/nginx/myproject.error.log;
# 静态文件服务 (Nginx直接处理)
location /static/ {
alias /path/to/your/project/staticfiles/; # 必须和STATIC_ROOT一致
expires 30d;
add_header Cache-Control "public";
access_log off;
}
# 媒体文件服务 (用户上传)
location /media/ {
alias /path/to/your/project/media/;
expires 30d;
add_header Cache-Control "public";
access_log off;
}
# 反向代理动态请求到 Gunicorn
location / {
# 传递必要的请求头
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;
# 关闭缓冲 (可选,根据场景调整)
proxy_buffering off;
# 连接超时设置
proxy_connect_timeout 90s;
proxy_send_timeout 90s;
proxy_read_timeout 90s;
# 代理到 Gunicorn (使用配置的 bind 地址)
proxy_pass http://unix:/run/gunicorn.sock; # 如果Gunicorn用socket
# proxy_pass http://127.0.0.1:8000; # 如果Gunicorn用端口
}
# 其他优化配置 (如gzip, client_max_body_size等)
client_max_body_size 100M; # 允许上传大文件
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
Ø 启用站点配置: 创建符号链接到 sites-enabled 目录。
bash
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
Ø 测试 Nginx 配置:sudo nginx -t (非常重要!确保语法正确)。
Ø 重启 Nginx:sudo systemctl restart nginx。
Ø 设置防火墙: 确保 80 和 443 端口开放。
获取 SSL 证书 (使用 Let's Encrypt / Certbot):Ø 安装 certbot 和 python3-certbot-nginx。
Ø 运行 sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com。
Ø 按照提示操作,Certbot 会自动修改 Nginx 配置并设置自动续期。
测试与监控:Ø 访问 和 (或其他已知静态文件) 验证整个栈是否正常工作。
Ø 检查 Nginx (/var/log/nginx/access.log, error.log) 和 Gunicorn (journalctl -u gunicorn) 日志是否有错误。
Ø 使用 top, htop, free -m 监控服务器资源 (CPU, 内存)。
Ø 使用 curl 或浏览器开发者工具检查响应头和状态码。
常见问题与优化点
静态文件 404: 最常见问题之一。检查:Ø STATIC_ROOT 设置是否正确。
Ø collectstatic 是否成功运行且文件存在。
Ø Nginx 配置中的 location /static/ 的 alias 路径是否正确,末尾是否有 /。
Ø 目录和文件的权限 ( 用户或 Nginx 运行用户是否有读取权限)。
Gunicorn 启动失败:Ø 检查 Systemd 日志 (journalctl -u gunicorn -xe)。
Ø 确保虚拟环境路径正确,依赖已安装。
Ø 确保 bind 地址可用且权限正确 (Unix socket 的目录 /run/ 通常需要 或特定组有权限)。
性能瓶颈:Ø 调整 Gunicorn workers 数量 (根据 CPU 核心数和应用类型 I/O 密集型或 CPU 密集型)。
Ø 考虑使用异步 worker (gevent, eventlet) 处理大量并发连接 (尤其 I/O 密集型应用)。
Ø 优化数据库查询 (Django Debug Toolbar 在开发时很有用)。
Ø 添加缓存 (Django 缓存框架 + Redis/Memcached)。
Ø Nginx 启用 Gzip 压缩。
Ø 考虑 CDN 分发静态文件。
安全性:Ø 永远 DEBUG = False!
Ø 使用强 SECRET_KEY 并通过环境变量设置。
Ø 正确配置 ALLOWED_HOSTS。
Ø 保持系统、Python 包、Nginx 更新。
Ø 使用 HTTPS (Certbot 自动续期)。
Ø 限制数据库用户权限。
Ø 考虑使用 Django 安全中间件 (如 django.middleware.security.SecurityMiddleware)。
Ø 定期审计代码和依赖 (如 safety check)。
总结
Django + Gunicorn + Nginx 的部署路径是一条经过实践检验的“黄金之路”。它清晰地划分了职责:
Nginx 作为前线卫士和加速器:处理静态文件、SSL、反向代理、缓冲、基础安全。Gunicorn 作为高效的 Python WSGI 服务器:管理 Django 进程、处理并发请求。Django 作为应用核心:专注业务逻辑和动态内容生成。这条路径提供了良好的性能、稳定性、安全性和可扩展性。通过遵循上述步骤,特别是注意配置细节(路径、权限、环境变量)和启用关键的生产设置(关闭 Debug、HTTPS),你可以成功地将 Django 应用部署到生产环境。后续的监控和持续优化(如缓存、异步任务队列 Celery + Redis)是保证应用长期健康运行的关键。
来源:老客数据一点号