Django经Apache反向代理部署后URL用127.0.0.1而非真实域名的修复方法
问题核心原因
Django生成绝对URL(尤其是邮件场景的全路径链接)时,会直接读取请求上下文中的Host头信息。当前Apache反向代理的默认行为是将传递给后端Gunicorn的Host头替换为ProxyPass配置里填写的127.0.0.1,加上Django侧的代理信任规则、站点绑定配置未匹配真实部署信息,最终导致所有自动生成的URL都指向本地回环地址。
分步修复方案
1. 补全Apache虚拟主机的请求转发规则
当前Location块仅配置了套接字转发逻辑,缺少原始请求头传递配置,需要修改为如下内容:
<Location /relayrace/> ProxyPass unix:/run/gunicorn-traverse.sock|http://127.0.0.1/ ProxyPassReverse unix:/run/gunicorn-traverse.sock|http://127.0.0.1/ # 保留客户端请求的原始Host头,避免被替换为127.0.0.1 ProxyPreserveHost On # 传递HTTPS协议标识,避免Django生成http开头的错误链接 RequestHeader set X-Forwarded-Proto "https" </Location>
ProxyPreserveHost On是这一步的核心配置,开启后Apache会将客户端请求携带的真实FQDN作为Host头传递给后端,不会自动替换为ProxyPass里填写的回环地址。
2. 调整Django项目的全局配置
在项目的settings.py文件中补充三类必要配置:
- 配置Host白名单,允许真实FQDN通过Django的安全校验:
ALLOWED_HOSTS = ["你的真实FQDN地址", "127.0.0.1"] - 配置代理信任规则,让Django识别Apache传递的HTTPS标识:
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") - 因服务部署在
/relayrace/子路径下,需要补充路径前缀配置,避免生成的URL缺失路径段:FORCE_SCRIPT_NAME = "/relayrace"
3. 修正django-allauth的站点绑定配置
django-allauth生成邮件链接时,不会直接读取请求的Host头,而是默认从django.contrib.sites模块读取站点域名,这部分配置存储在数据库中,是独立于settings.py的:
- 登录Django后台,进入「站点管理」页面
- 修改默认Site对象的Domain字段,将默认的
127.0.0.1:8000替换为你的真实FQDN - 确认settings.py中的
SITE_ID值和修改的站点ID保持一致(默认新建项目对应ID为1)
生效验证与常见踩坑
- 所有配置修改完成后,先执行
apachectl configtest校验Apache配置语法,确认无报错后重载Apache服务 - 重启对应的Systemd托管的Gunicorn服务,让Django侧的配置变更生效
- 验证时优先触发一次allauth的密码重置邮件,检查生成的链接域名、协议、路径是否完全匹配真实部署地址,不要依赖浏览器端的相对路径跳转结果验证
内容的提问来源于stack exchange,提问作者guettli
相关产品推荐
相关产品推荐

