本地搭建Django生产环境:Gunicorn+Nginx静态文件加载异常排查
让我们一步步拆解你的问题,找出配置里的几个关键错误:
核心错误点
1. Nginx与Gunicorn端口冲突
你当前的Nginx配置监听8000端口,同时Gunicorn也启动在8000端口——这会导致其中一个服务无法正常启动(端口被占用)。如果Nginx没启动成功,所有请求都会直接打到Gunicorn,而Gunicorn本身不负责处理静态文件,这就是静态文件加载失败的直接原因之一。
2. 静态文件路径不匹配
你的Django settings.py中设置STATIC_URL = '/static/',意味着浏览器会请求http://127.0.0.1:8000/static/xxx这样的静态文件路径,但Nginx配置的是location /production_static/,根本不会拦截这些请求,自然无法返回静态文件。
3. 静态文件目录映射错误
即使路径匹配,你当前的root配置也无法正确指向collectstatic生成的静态文件目录。root和alias的逻辑不同:root会把location路径拼接到root指定的目录后,而你需要的是直接映射到production_static目录。
4. 缺少媒体文件配置
你的settings.py中配置了MEDIA_URL和MEDIA_ROOT,但Nginx里没有对应的处理规则,后续如果有媒体文件也会出现加载问题。
修正后的配置方案
第一步:调整Gunicorn启动端口
先把Gunicorn改到其他端口(比如8001),避免和Nginx冲突:
gunicorn mydjangoproject.wsgi:application --bind 127.0.0.1:8001
第二步:修改Nginx配置文件
更新/etc/nginx/sites-available/mydjangoproject的内容:
server { listen 8000; server_name 127.0.0.1; # 忽略favicon.ico的日志 location = /favicon.ico { access_log off; log_not_found off; } # 处理静态文件:匹配Django的STATIC_URL,直接指向collectstatic生成的目录 location /static/ { alias /home/john/Documents/Django_projects/mydjangoproject/Version_2/production_static/; # 可选:添加缓存优化静态文件加载 expires 30d; add_header Cache-Control "public, max-age=2592000"; } # 处理媒体文件:匹配Django的MEDIA_URL location /media/ { alias /home/john/Documents/Django_projects/mydjangoproject/Version_2/media/; } # 转发动态请求到Gunicorn location / { include proxy_params; proxy_pass http://127.0.0.1:8001; # 对应Gunicorn的新端口 } }
验证步骤
- 先停止当前运行的Gunicorn和Nginx服务。
- 用新的端口启动Gunicorn(如上命令)。
- 测试Nginx配置是否正确:
sudo nginx -t - 重启Nginx生效:
sudo systemctl restart nginx - 访问
http://127.0.0.1:8000,检查静态文件是否正常加载。
额外提醒
如果不确定STATIC_ROOT的绝对路径是否正确,可以在Django项目根目录下执行以下命令确认:
python manage.py shell -c "import os; print(os.path.join(os.path.dirname(os.path.abspath('manage.py')), 'production_static/'))"
确保Nginx配置中的alias路径和输出的路径完全一致。
内容的提问来源于stack exchange,提问作者Eternal_Ether

