settings.py中Debug=False时Nginx无法加载用户上传媒体图片
问题:Django+Nginx部署下图片无法显示,Content-Type识别错误
我用Nginx部署的Django网站此前运行正常,近期出现图片加载失败的问题。通过curl排查发现,图片请求返回的Content-Type错误——本该返回image/jpeg,实际返回text/html; charset=utf-8。开启Debug=True时问题消失,Debug=False时问题复现。部署环境为AWS EC2实例,数据库使用AWS RDS PostgreSQL。
相关配置文件
Settings.py 关键配置
STATIC_URL = '/home/ubuntu/static/' MEDIA_URL = "/home/ubuntu/media/" STATIC_ROOT = '/home/ubuntu/static' MEDIA_ROOT = '/home/ubuntu/media/' ONNGO_DOMAIN = "https://onngo.co.in" PROFILE_PICTURE_URL = MEDIA_ROOT+"profile_pictures/" STATICFILES_DIRS = ( os.path.join(CORE_DIR, 'apps/static'), )
Nginx 主配置(nginx.conf)
user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; types_hash_max_size 2048; # server_tokens off; server_names_hash_bucket_size 512; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; #gzip_vary on; #gzip_proxied any; #gzip_comp_level 6; #gzip_buffers 16 8k; #gzip_http_version 1.1; #gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/core; } #mail { # # See sample authentication script at: # # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript # # # auth_http localhost/auth.php; # # pop3_capabilities "TOP" "USER"; # # imap_capabilities "IMAP4rev1" "UIDPLUS"; # # server { # listen localhost:110; # protocol pop3; # proxy on; # } # # server { # listen localhost:143; # protocol imap; # proxy on; # } #}
Nginx 站点配置(/etc/nginx/sites-enabled/core)
server{ server_name onngo.co.in; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { alias /home/ubuntu/static; } location /ubuntu/media/ { alias /home/ubuntu/media; } location / { include proxy_params; proxy_read_timeout 300s; proxy_connect_timeout 75s; proxy_pass http://unix:/run/gunicorn.sock; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/onngo.co.in/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/onngo.co.in/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server{ server_name www.onngo.co.in; # managed by Certbot location = /favicon.ico { access_log off; log_not_found off; } location /static/ { alias /home/ubuntu/static; } location /media/ { autoindex on; alias /home/ubuntu/media; } location / { include proxy_params; proxy_read_timeout 300s; proxy_connect_timeout 75s; proxy_pass http://unix:/run/gunicorn.sock; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/onngo.co.in/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/onngo.co.in/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot }server{ if ($host = onngo.co.in) { return 301 https://$host$request_uri; } # managed by Certbot listen 80 default_server; server_name onngo.co.in; return 404; # managed by Certbot }server{ if ($host = www.onngo.co.in) { return 301 https://$host$request_uri; } # managed by Certbot listen 80 ; server_name www.onngo.co.in; return 404; # managed by Certbot }
问题根源与修复方案
1. 修正Django的URL前缀配置
STATIC_URL和MEDIA_URL是前端访问资源的URL路径前缀,不是服务器本地绝对路径。当前错误的配置导致生成的资源URL无法匹配Nginx的location规则,请求被转发给Gunicorn后返回404页面(Content-Type为text/html)。
修改Settings.py:
# 改为URL路径前缀,而非本地路径 STATIC_URL = '/static/' MEDIA_URL = '/media/' # 本地存储路径保持不变 STATIC_ROOT = '/home/ubuntu/static' MEDIA_ROOT = '/home/ubuntu/media/'
2. 统一Nginx的media location规则
onngo.co.in的server块中,media的location规则为/ubuntu/media/,与实际URL前缀不匹配,需和www.onngo.co.in的配置统一,同时给alias路径加上斜杠避免匹配异常:
修正后的onngo.co.in server块中media部分:
location /media/ { autoindex on; alias /home/ubuntu/media/; }
3. 重新收集静态文件
执行Django静态文件收集命令,确保静态资源正确同步到STATIC_ROOT:
python manage.py collectstatic --noinput
4. 重启服务生效
# 重启Gunicorn systemctl restart gunicorn # 重启Nginx systemctl restart nginx
验证
用curl测试图片URL,确认Content-Type正确:
curl -I https://onngo.co.in/media/profile_pictures/your-image.jpg
此时应返回Content-Type: image/jpeg,图片可正常显示。
内容的提问来源于stack exchange,提问作者Mayank Patel
相关产品推荐
相关产品推荐

