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

Django django-hosts配置子域名生产环境静态文件加载异常

针对子域名静态文件丢失问题的修复方案

主域静态文件正常、仅子域名异常,本质是生产环境静态文件请求不经过Django处理,django-hosts的本地调试逻辑在生产环境不生效,按以下顺序排查修复即可:

  • 先校验web服务器层的静态路由匹配规则
    这是90%同类问题的根因:本地DEBUG模式下Django会自动接管所有路径的静态文件请求,不校验域名;但生产环境不管是用Nginx反向代理还是DigitalOcean App Platform的静态托管,静态文件规则默认可能只匹配主域。
    • 如果用Nginx:给子域名对应的server块和主域的server块配置完全一致的静态资源映射规则,参考配置:
      location /static/ {
          alias /your/project/path/staticfiles/;
          expires 30d;
          add_header Cache-Control "public, immutable";
      }
      location /media/ {
          alias /your/project/path/media/;
          expires 7d;
      }
      
      配置完重载Nginx后,直接访问https://executives.kingdomleadsafrica.org/static/[确认存在的静态文件名]验证,如果能直接访问到文件就说明web层规则正常。
    • 如果用DigitalOcean App Platform:去控制台的静态资源配置页,把静态路径规则的绑定域名从仅主域改为*.kingdomleadsafrica.org,确保子域名的静态请求能命中托管规则。
  • 校验Django侧配置
    • 确认STATIC_URL = '/static/',必须以斜杠开头写绝对路径,不要写相对路径static/,否则子域名下会把静态路径解析为子域名下的二级路径导致404。如果配置了静态资源独立域名,直接写全路径https://kingdomleadsafrica.org/static/即可,不需要给静态资源单独做子域名解析。
    • 检查中间件顺序:django_hosts.middleware.HostsRequestMiddleware必须放在django.middleware.common.CommonMiddleware之前,避免请求被CommonMiddleware重写路径。子域名对应的urlconf不要加开发环境用的static()调试路由,生产环境DEBUG=False时该路由不生效,反而可能干扰路由匹配。
    • 重新执行python manage.py collectstatic --noinput,确认所有应用的静态文件都被正确收集到STATIC_ROOT目录,避免子域名引用的专属静态文件没被收集。
  • 快速定位技巧:看web服务器的访问日志,如果子域名的静态文件请求被转发到了Gunicorn/Django进程,就说明静态路由规则没匹配上;如果请求命中了静态规则还是返回404,就是静态文件目录的alias路径配置错误,或者文件没收集全。
不依赖django-hosts的子域名实现方案

以下都是生产环境验证过的方案,按性能和维护成本从高到低排序:

  • 方案1:Nginx层做子域名路由分发(性能最优)
    完全把域名判断逻辑放到web服务器层,不需要Django引入额外依赖。如果子域名和主域共用一套Django代码:给每个子域名写独立的Nginx server块,转发请求时加自定义请求头标记来源,比如给executives子域名的请求加X-Site-Id: executives,然后在Django根urlconf里写个简单的判断逻辑,根据请求头的值include对应应用的路由即可,核心代码不超过10行。如果子域名功能和主站耦合度极低,直接给子域名反向代理到独立运行的Gunicorn进程,代码完全隔离,排查问题更简单。
  • 方案2:Django原生sites框架+轻量路由判断(最轻量)
    用Django自带的django.contrib.sites框架,不需要安装第三方包。在后台分别为主域和子域名创建对应的Site实例,写个简单的中间件把当前请求对应的Site对象绑定到request上,根urlconf里根据request.get_host()的值动态加载对应应用的路由即可,逻辑完全可控,不会出现第三方包的兼容问题。
  • 方案3:架构拆分(维护成本最低)
    如果子域名对应的业务模块独立性强,直接把子域名部署为独立的Django服务,和主站共享同一个数据库即可。DigitalOcean平台原生支持给不同服务绑定独立子域名,代码层完全不需要做任何域名判断逻辑,不会出现一个子域名配置错误影响主站的问题。

内容的提问来源于stack exchange,提问作者Ojo Philip Odeniyi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 20:06:40