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

如何通过Docker配合宿主机Nginx正确提供Django媒体文件访问服务

问题根因

  • 宿主机Nginx的/media/规则同时配置了proxy_pass和alias,属于配置冲突,Nginx无法判断是转发请求给Django还是读取本地文件
  • alias /app/media_cdn/指向的是Docker容器内部的路径,宿主机上不存在该路径,就算去掉proxy_pass也无法找到对应文件
  • 如果你未在Django路由中配置媒体文件访问规则,Django的runserver默认不会处理媒体文件请求,就算转发到8400端口也会返回404

解决方案(推荐优先使用方案一,性能更高更稳定)

方案一:宿主机Nginx直接读取媒体文件(生产环境推荐)

  1. 首先查询Docker命名卷media-cdn-data在宿主机的实际挂载路径,执行命令:
    docker volume inspect media-cdn-data
    返回结果中的Mountpoint字段就是媒体文件在宿主机的实际存储路径,通常格式类似/var/lib/docker/volumes/[你的项目名]_media-cdn-data/_data
  2. 替换宿主机Nginx的/media/配置,删除原有冲突项,最终配置如下:
location /media/ {
    alias 刚才查到的Mountpoint路径/;
    expires 30d;
    add_header Cache-Control "public, immutable";
}
  1. 权限校验:确保Nginx运行用户(通常是www-data)有该路径的读取权限,若出现权限不足可以执行命令赋予目录读权限:chmod -R o+rx 刚才查到的Mountpoint路径

方案二:请求转发给Django处理(仅适合临时调试使用)

  1. 先在Django项目根路由urls.py中添加媒体文件路由规则:
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # 原有路由保持不变
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  1. 修改宿主机Nginx的/media/配置,删除alias项,避免和proxy_pass冲突,注意proxy_pass末尾不要加斜杠,否则会丢失/media/前缀:
location /media/ {
    proxy_pass http://127.0.0.1:8400;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

生效与排查

  • 修改Nginx配置后先执行nginx -t校验配置语法是否正确,再执行nginx -s reload重载配置
  • 可以查看Nginx错误日志/var/log/nginx/error.log确认具体报错原因,快速定位问题
  • 进入容器确认媒体文件确实存在:docker exec -it [你的backend容器ID/名称] ls /app/media_cdn

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:45:03