You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

预生产环境Nginx返回Django媒体URL 404,开发环境正常

问题分析与解决方法

核心原因

当Django的DEBUG=False时,你代码里的static(settings.MEDIA_URL, ...)不会生效——这行代码仅在开发环境(DEBUG=True)下由runserver启用,预生产环境用gunicorn启动时,Django根本没配置/media的路由,所以Nginx把/media请求转发到后端后,自然返回404。

推荐解决方案:Nginx直接托管媒体文件(生产环境最优)

Django不适合在生产环境处理静态/媒体文件,让Nginx直接serve是标准做法,步骤如下:

1. 配置Docker挂载媒体目录

在docker-compose.yml中,给Nginx服务添加媒体目录的挂载,把后端容器的MEDIA_ROOT目录映射到Nginx容器的某个路径。比如后端的MEDIA_ROOT是/app/backend/media,则Nginx的volumes配置:

services:
  nginx:
    ...
    volumes:
      - ./backend/media:/usr/share/nginx/media  # 左边是本地/后端容器的媒体路径,右边是Nginx容器内的路径
      - ./nginx.conf:/etc/nginx/nginx.conf
  backend:
    ...
    volumes:
      - ./backend/media:/app/backend/media  # 确保后端容器能读写媒体文件

2. 修改Nginx配置

把之前合并的location ~ ^/(api|media)/拆分成两个独立的location块:

http {
    client_max_body_size 5M;

    upstream backend_api {
        server backend:8000;
    }

    server {
        listen 80;

        include /etc/nginx/mime.types;

        root /usr/share/nginx/html;
        index index.html;

        location = /favicon.ico {
            access_log off;
            log_not_found off;
        }

        # 处理API请求
        location /api {
            proxy_pass http://backend_api;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_redirect off;
        }

        # 直接托管媒体文件
        location /media {
            alias /usr/share/nginx/media;  # 对应上面挂载的Nginx容器内路径
            expires 30d;  # 可选,设置浏览器缓存,优化性能
            add_header Cache-Control "public, max-age=2592000";
        }

        location / {
            try_files $uri $uri/ /index.html;
        }
    }
}

3. 验证Django配置

确保settings.py里的媒体路径配置正确:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')  # 路径要和docker挂载的一致

备选方案:让Django处理媒体文件(不推荐)

如果因为某些原因必须让Django处理媒体请求,可以用whitenoise库:

  1. 安装whitenoise:
pip install whitenoise
  1. 修改settings.py:
INSTALLED_APPS = [
    # 放在django.contrib.staticfiles前面
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    # 其他app...
]

MIDDLEWARE = [
    # 放在SecurityMiddleware之后,其他中间件之前
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # 其他中间件...
]

# 配置媒体文件处理
WHITENOISE_MEDIA_PREFIX = '/media/'

这样Django就能在DEBUG=False时处理/media请求,但性能不如Nginx直接托管,只适合小型场景。

额外检查点

  • 确保媒体文件确实存在于后端的MEDIA_ROOT目录下,且文件权限正确(Nginx容器的用户能读取,比如设置目录权限为755,文件为644)。
  • 重启Nginx和后端容器,确保配置生效。

内容的提问来源于stack exchange,提问作者lbris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:24:44