Django django-hosts配置子域名生产环境静态文件加载异常
针对子域名静态文件丢失问题的修复方案
主域静态文件正常、仅子域名异常,本质是生产环境静态文件请求不经过Django处理,django-hosts的本地调试逻辑在生产环境不生效,按以下顺序排查修复即可:
- 先校验web服务器层的静态路由匹配规则
这是90%同类问题的根因:本地DEBUG模式下Django会自动接管所有路径的静态文件请求,不校验域名;但生产环境不管是用Nginx反向代理还是DigitalOcean App Platform的静态托管,静态文件规则默认可能只匹配主域。- 如果用Nginx:给子域名对应的
server块和主域的server块配置完全一致的静态资源映射规则,参考配置:
配置完重载Nginx后,直接访问location /static/ { alias /your/project/path/staticfiles/; expires 30d; add_header Cache-Control "public, immutable"; } location /media/ { alias /your/project/path/media/; expires 7d; }https://executives.kingdomleadsafrica.org/static/[确认存在的静态文件名]验证,如果能直接访问到文件就说明web层规则正常。 - 如果用DigitalOcean App Platform:去控制台的静态资源配置页,把静态路径规则的绑定域名从仅主域改为
*.kingdomleadsafrica.org,确保子域名的静态请求能命中托管规则。
- 如果用Nginx:给子域名对应的
- 校验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
相关产品推荐
相关产品推荐

