NGINX与Django部署中静态文件加载异常问题求助
Django静态文件与媒体文件部署问题排查
问题概述
为父亲搭建的摄影作品展示网站从共享主机迁移到Ubuntu VPS后,网站可访问,但模板及管理面板CSS失效、图片无法显示。已设置ImageField(upload_to='media'),但图片未存入指定文件夹,浏览器路径显示异常。本地运行正常,生产环境(DEBUG=False)出现问题。
已执行的权限配置命令
DEBUG = False sudo chown -R www-data:www-data /home/dave/mhprints/static sudo chmod -R 777 /home/dave/mhprints/static sudo chown -R www-data:www-data /home/dave/mhprints/staticfiles sudo chmod -R 777 /home/dave/mhprints/staticfiles sudo chmod -R 777 /var/www/staticfiles sudo chmod -R 777 /var/www/staticfiles
项目目录结构

/var目录结构

settings.py路径与URL配置
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media') STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static') ] CKEDITOR_UPLOAD_PATH = "uploads/"
urls.py配置
from django.contrib import admin from django.urls import path, include from django.conf.urls.static import static from django.conf import settings from django.contrib.staticfiles.urls import staticfiles_urlpatterns urlpatterns = [ path('admin/', admin.site.urls), path('', include('mhpapp.urls')), path('ckeditor/', include('ckeditor_uploader.urls')), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Nginx sites_enabled/mhprints配置文件
server { listen 80; server_name my_ip; location = /favicon.ico { access_log off; log_not_found off; } location /static { root /var/www; } location /media { root /var/www/static; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; } }
问题排查与修复方案
1. 静态文件Nginx配置错误
当前Nginx中/static的root指向/var/www,会导致Nginx去/var/www/static查找静态文件,但执行collectstatic后,静态文件实际存储在项目的staticfiles目录(/home/dave/mhprints/staticfiles)。修改Nginx配置:
location /static { alias /var/www/staticfiles; # 用alias替代root,避免路径拼接错误 }
同时需执行python manage.py collectstatic将静态文件收集到STATIC_ROOT,再同步到/var/www/staticfiles,或直接将STATIC_ROOT修改为/var/www/staticfiles后重新执行收集命令。
2. 媒体文件路径不匹配
MEDIA_ROOT设置为项目目录下的static/media,但Nginx中/media的root指向/var/www/static,导致查找路径与实际存储路径不一致。- 修复二选一:
- 修改
MEDIA_ROOT为/var/www/media,确保上传图片存储到该目录; - 修改Nginx配置:
location /media { alias /home/dave/mhprints/static/media; # 指向实际的MEDIA_ROOT路径 }
- 修改
- 额外说明:
ImageField(upload_to='media')会在MEDIA_ROOT下多一层media子目录,若不需要可将upload_to设为空字符串,或调整MEDIA_ROOT为os.path.join(BASE_DIR, 'media')。
3. DEBUG=False时static()函数失效
Django的static()函数在DEBUG=False时不生效,生产环境必须由Nginx处理静态/媒体文件,无需依赖Django的URL配置,确保Nginx路径与实际存储路径完全匹配即可。
4. 权限优化(替代777)
777权限存在安全风险,改为给www-data用户必要权限:
sudo chown -R www-data:www-data /home/dave/mhprints/static/media sudo chmod -R 755 /home/dave/mhprints/static sudo chmod -R 755 /home/dave/mhprints/staticfiles sudo chown -R www-data:www-data /var/www/staticfiles sudo chmod -R 755 /var/www/staticfiles
5. 验证步骤
- 执行
python manage.py collectstatic确认静态文件收集完成; - 上传测试图片,检查实际存储路径是否与
MEDIA_ROOT一致; - 重启Nginx:
sudo systemctl restart nginx; - 清除浏览器缓存后刷新页面,验证静态文件与图片加载状态。
内容的提问来源于stack exchange,提问作者David Henson
相关产品推荐
相关产品推荐

