Docker同网络跨容器访问Django报Invalid HTTP_HOST header问题求助
根因说明
报错来自两层问题:
- Django默认的HTTP_HOST头校验逻辑,对非
localhost的单标签主机名(即不带.的短名称,比如你直接用的Docker容器名nginx)会直接判定不符合RFC 1034/1035规范,这层校验优先级高于ALLOWED_HOSTS匹配,哪怕你把短名加进允许列表也会被拦截。 - 容器环境下修改
settings.py后如果没重启Django容器,配置根本不会加载,这是改配置时最常见的低级失误。
解决方法
按优先级试,第一种是测试环境成本最低的方案:
方案1:使用带点的网络别名访问,避开校验规则
直接在docker-compose.yml里给Nginx服务加一个符合标准域名格式的网络别名,从根源绕开单标签主机名的校验问题,不需要改动Django核心逻辑:
services: nginx: # 保留你原有的镜像、端口、挂载等配置 networks: default: aliases: - nginx.test
执行docker-compose up -d重建网络使别名生效,之后修改三处配置:
- 把Selenium脚本里的访问地址改为
driver.get("http://nginx.test:80") - 在Django的
settings.py里把"nginx.test"加入ALLOWED_HOSTS列表 - 重启Django容器:
docker-compose restart django
方案2:必须用短名nginx访问时,修改Django校验正则
如果不想调整访问地址,直接在settings.py里重写Django的Host校验正则,放行单标签短名,在配置文件任意位置添加以下代码:
import re import django.http.request django.http.request.host_validation_re = re.compile(r"^([a-z0-9._-]+|\[[0-9a-f:]+\])(?::\d+)?$")
确认ALLOWED_HOSTS里已经添加"nginx"后重启Django容器即可。
方案3:排查Nginx代理配置
如果以上操作后仍报错,检查Nginx反向代理的location配置块,必须添加Host头传递规则,否则传给Django的Host头会不符合预期:
location / { proxy_pass http://你的Django服务容器地址:端口; proxy_set_header Host $host; # 缺少这行就会出现Host头异常 proxy_set_header X-Real-IP $remote_addr; }
修改后执行docker-compose exec nginx nginx -s reload重载配置。
校验步骤
所有配置修改完成后,先进入Selenium容器执行curl命令验证连通性:
curl -v http://你配置的访问地址
如果curl能正常拿到Django返回的200响应,再运行Selenium测试脚本,避免在Selenium层面浪费时间排查问题。
内容的提问来源于stack exchange,提问作者Nabiu
相关产品推荐
相关产品推荐

