生产环境下Django媒体文件无法访问(404错误)求助
我已经翻遍了Stack Overflow相关问题,还是没找到解决办法,现在把问题列出来:
配置信息
- Nginx.conf 配置:
location /media/ { alias /root/server/media/; } location /static/ { alias /root/server/static/; }
- urls.py 配置:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
- settings.py 配置:
STATIC_URL = '/static/' STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static/'),) STATIC_ROOT = os.path.join(BASE_DIR, '/static/') MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') MEDIA_URL = '/media/' STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
- wsgi.py 配置:
application = WhiteNoise(application, root=os.path.join(BASE_DIR, 'static')) application = WhiteNoise(application, root=os.path.join(BASE_DIR, 'media'))
我确认所有配置都做了,服务器上/root/server/media/images/1.png文件也确实存在,但访问$serverlink/media/images/1.png时还是404,有没有大佬知道原因?
我来帮你排查几个常见的坑,你可以逐一验证:
1. Nginx权限与路径斜杠问题
首先,/root目录的默认权限非常严格,Nginx进程(通常以www-data用户运行)大概率没有访问权限。先给目录设置正确的权限:
chown -R www-data:www-data /root/server/media chmod -R 755 /root/server/media
另外,检查Nginx的alias路径斜杠是否匹配:如果location /media/末尾带斜杠,alias的路径末尾也必须带斜杠,否则会导致路径拼接错误。你当前的配置看起来斜杠是一致的,但可以试试去掉两边的斜杠再测试:
location /media { alias /root/server/media; }
2. Django STATIC_ROOT配置错误
你settings里的STATIC_ROOT = os.path.join(BASE_DIR, '/static/')多了个开头的斜杠,这会让os.path.join直接忽略BASE_DIR,生成绝对路径/static/而不是/root/server/static/。修正为:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
虽然这主要影响静态文件,但配置错误可能会干扰Django的静态/媒体文件处理逻辑,先把这个坑填上。
3. WhiteNoise与Nginx的冲突
你在wsgi.py里重复初始化了WhiteNoise,还把Media目录也加进去了,但Media文件应该由Nginx直接处理,不需要WhiteNoise介入——当Nginx配置了/media/的location后,请求会直接被Nginx拦截,根本不会传到Django。删掉wsgi.py里的第二行:
# 移除这行多余的配置 # application = WhiteNoise(application, root=os.path.join(BASE_DIR, 'media'))
4. 确认BASE_DIR的实际值
有时候BASE_DIR并不是你预期的/root/server,导致MEDIA_ROOT拼接错误。在settings.py里加一行调试代码:
print("BASE_DIR:", BASE_DIR) print("MEDIA_ROOT:", MEDIA_ROOT)
然后运行python manage.py shell,看看输出的路径是不是/root/server/media/。如果不是,检查BASE_DIR的定义是否正确。
5. 重载Nginx配置
修改Nginx配置后,一定要执行重载命令让新配置生效:
sudo nginx -s reload
很多人改了配置忘了这一步,导致旧配置还在运行,自然访问失败。
按这个顺序排查下来,应该能解决你的404问题~
内容的提问来源于stack exchange,提问作者user14491987




