生产环境uWSGI必须用socket模式(如unix:///tmp/myproject.sock)并正确设置chmod-socket、chown-socket和vacuum;Nginx需透传Host、X-Forwarded-Proto等头,Django需配置ALLOWED_HOSTS、SECURE_PROXY_SSL_HEADER及静态文件由Nginx直接服务。

uWSGI配置里socket和http模式不能混用
很多新手直接照抄教程,把http = :8000和socket = /tmp/uwsgi.sock写在同一份配置里,结果Django跑起来了但Nginx连不上——因为http模式让uWSGI自己监听HTTP请求,绕过了Nginx;而socket模式才是给Nginx反向代理用的Unix域套接字或TCP端口。
生产环境必须用socket(推荐unix:///tmp/myproject.sock),并确保chmod-socket = 664、chown-socket = www-data:www-data,否则Nginx会报connect() to unix:///tmp/myproject.sock failed (13: Permission denied)。
-
socket路径要和Nginx的proxy_pass地址严格一致 - 禁用
http、http-socket等参数,避免端口冲突或协议错位 - 加
vacuum = true,防止worker退出后socket文件残留导致启动失败
Nginx反向代理配置里proxy_set_header漏掉Host和X-Forwarded-Proto
Django在生产环境依赖request.META['HTTP_HOST']和request.is_secure()做URL生成和重定向,如果Nginx没透传关键头,admin页面跳转会变成http://example.com/admin/(即使你配了HTTPS),或者static资源404——因为Django以为自己跑在HTTP下,拼错了STATIC_URL前缀。
必须显式设置:
立即学习“Python免费学习笔记(深入)”;
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;
-
$scheme不是固定写https,它由Nginx根据客户端实际连接协议自动取值 - 别用
proxy_redirect default,Django的SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')才起效 - 如果Nginx前面还有CDN或WAF,
X-Forwarded-For可能被覆盖,得配合real_ip_header和set_real_ip_from
Django的DEBUG=False不等于安全,漏配ALLOWED_HOSTS直接500
只要DEBUG=False,Django就会校验Host头是否在ALLOWED_HOSTS里。Nginx转发过来的Host是域名(比如myapp.com),不是127.0.0.1或localhost——所以ALLOWED_HOSTS = ['*']看似能跑通,但违反安全策略,且在DEBUG=False时会被Django拒绝(SuspiciousOperation)。
- 填具体域名:
ALLOWED_HOSTS = ['myapp.com', 'www.myapp.com'] - 支持子域名用
.myapp.com(注意开头的点) - 如果Nginx用IP访问uWSGI(比如
proxy_pass http://127.0.0.1:8001),则需加'127.0.0.1',但不建议这种写法 - 别忘了
SECRET_KEY必须换掉默认值,且不能硬编码在settings.py里
静态文件没走Nginx,Django自己在serve
开发时python manage.py runserver会自动处理/static/,但uWSGI下Django根本不处理静态路径——如果你没配Nginx的location /static/,所有CSS/JS都会404;更糟的是,有人误开django.contrib.staticfiles的runserver逻辑,用whitenoise或serve视图强行让Django发静态文件,这在生产环境会吃光worker进程、拖慢整个应用。
正确做法只有一条:Nginx直接读文件,不经过uWSGI。
location /static/ {
alias /path/to/your/staticfiles/;
expires 1y;
add_header Cache-Control "public, immutable";
}
-
alias末尾必须带/,且路径要和python manage.py collectstatic输出目录完全一致 - 别用
root代替alias,否则URL映射会多一层目录 -
collectstatic必须在部署时运行,不能靠uWSGI启动时自动触发
权限、路径、头信息、协议透传——这些地方错一个,服务就卡在某个看似无关的环节。最常被跳过的其实是chown-socket和ALLOWED_HOSTS,而不是代码本身。










