本地搭建Django生产环境:Gunicorn+Nginx静态文件缺失排查
嘿,我来帮你梳理下问题所在——你现在的核心问题是Nginx配置和Django的静态文件设置不匹配,还有一个容易忽略的端口冲突问题,咱们一步步来解决:
1. 先解决最明显的静态文件路径不匹配
你的Django settings.py里设置了STATIC_URL = '/static/',这意味着页面里的静态文件引用都是/static/css/xxx.css这种格式,但你的Nginx配置里只处理了/production_static/路径,完全没匹配上浏览器实际请求的/static/前缀,导致这些请求都被转发给了Gunicorn(而Gunicorn本来就不负责静态文件服务),所以静态文件加载失败。
2. 修正Nginx的静态文件目录映射
你的STATIC_ROOT = os.path.join(BASE_DIR, 'production_static/'),假设BASE_DIR是包含manage.py的项目根目录(也就是/home/john/Documents/Django_projects/mydjangoproject/Version_2/),那么静态文件的实际存储路径是/home/john/Documents/Django_projects/mydjangoproject/Version_2/production_static/。但你Nginx里的root指向了项目的子应用目录,这会导致Nginx找错文件位置。
修复后的完整Nginx配置
把/etc/nginx/sites-available/mydjangoproject替换成下面的内容:
server { listen 8000; server_name 127.0.0.1; location = /favicon.ico { access_log off; log_not_found off; } # 匹配Django的STATIC_URL,直接指向静态文件存储目录 location /static/ { alias /home/john/Documents/Django_projects/mydjangoproject/Version_2/production_static/; } # 可选:如果你的项目用到了媒体文件,加上这段处理/media/路径 location /media/ { alias /home/john/Documents/Django_projects/mydjangoproject/Version_2/media/; } location / { include proxy_params; # 注意这里的端口要和Gunicorn监听的端口一致(后面会改) proxy_pass http://127.0.0.1:8001; } }
这里用alias而不是root是因为alias会直接替换掉location里的路径前缀,更适合静态文件目录的映射,避免路径拼接错误。
3. 解决端口冲突问题!
你现在的配置里,Gunicorn默认监听8000端口,Nginx也配置了listen 8000,这会导致端口冲突——要么Nginx启动失败,要么Gunicorn无法绑定端口。必须把其中一个的端口改掉:
- 启动Gunicorn时指定监听
8001端口:
gunicorn --bind 127.0.0.1:8001 mydjangoproject.wsgi
- 确保Nginx配置里的
proxy_pass指向http://127.0.0.1:8001(上面的配置已经改好了)
4. 验证修复步骤
- 先确认你已经执行过
python manage.py collectstatic,并且production_static目录里已经有所有静态文件(可以进去看看有没有css、js这些文件夹) - 重启Nginx:
sudo systemctl restart nginx - 停止之前的Gunicorn进程,用上面的新命令重新启动
- 访问
http://127.0.0.1:8000,检查静态文件是否正常加载
额外验证你的Django配置
你的settings.py配置是符合生产环境要求的:
DEBUG = False:正确,生产环境必须关闭调试模式ALLOWED_HOSTS = ['*']:本地测试没问题,正式部署时要改成具体域名STATIC_ROOT和STATICFILES_DIRS的设置正确,collectstatic会把STATICFILES_DIRS里的文件收集到STATIC_ROOT目录
内容的提问来源于stack exchange,提问作者Eternal_Ether

