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

部署Nginx+Gunicorn+Django遇DisallowedHost及400错误求助

Django部署Nginx+Gunicorn遭遇DisallowedHost与400错误排查方案

问题背景

首次部署Django项目likarnet到DigitalOcean Ubuntu服务器,采用Nginx+Gunicorn架构,已完成域名likarnet.com绑定公网IP及SSL配置,但持续出现DisallowedHost异常、400 Bad Request响应及Invalid HTTP_HOST header错误,常规方案尝试后无效。

环境版本

  • Python 3.12
  • Django 5.0.6

相关配置文件

1. Nginx配置(/etc/nginx/sites-available/likarnet)

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name likarnet.com www.likarnet.com;

        access_log  /var/log/nginx/access.log;
        error_log  /var/log/nginx/error.log;

        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/likarnet/website/likarnet;
        }

        location /media/ {
            root /home/likarnet/website/likarnet;
        }

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_redirect off;
            proxy_pass http://unix:/run/gunicorn.sock;
        }
}

也曾尝试替换为默认的include proxy_params;配置。

2. Gunicorn服务配置(/etc/systemd/system/gunicorn.service)

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=likarnet
Group=sudo
WorkingDirectory=/home/likarnet/website/likarnet
ExecStart=/home/likarnet/venv/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          --chdir=/home/likarnet/website/likarnet \
          likarnet.wsgi:application

[Install]
WantedBy=multi-user.target

测试结果

  • 运行python3 manage.py runserver 127.0.0.1:8000或0.0.0.0:8000后,执行curl -v localhost:8000返回301重定向,终端打印的ALLOWED_HOSTS包含['likarnet.com', '.likarnet.com', '64.225.77.248', '127.0.0.1', 'localhost']
  • 执行curl --unix-socket /run/gunicorn.sock localhost返回400 Bad Request页面
  • 浏览器访问likarnet.com显示ERR_CONNECTION_REFUSED
  • 执行curl -v localhost:80返回400 Bad Request响应

错误日志回溯

ERROR 2024-06-22 06:26:47,521 /home/likarnet/venv/lib/python3.12/site-packages/django/core/handlers/exception.py  124 Func: response_for_exception Task: None Process:  1274 MainProcess Thread:  133201422356608 MainThread Message: Invalid HTTP_HOST header: 'localhost'. You may need to add 'localhost' to ALLOWED_HOSTS. StackInfo: None
Traceback (most recent call last):
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/utils/deprecation.py", line 133, in __call__
    response = self.process_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/middleware/common.py", line 48, in process_request
    host = request.get_host()
           ^^^^^^^^^^^^^^^^^^
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/http/request.py", line 162, in get_host
    raise DisallowedHost(msg)
django.core.exceptions.DisallowedHost: Invalid HTTP_HOST header: 'localhost'. You may need to add 'localhost' to ALLOWED_HOSTS.

排查方向与解决方案

  1. 确认ALLOWED_HOSTS配置生效

    • 检查生产环境settings.py,确保ALLOWED_HOSTS包含localhost、127.0.0.1、likarnet.com、www.likarnet.com及服务器公网IP。注意:Django 5.0+已废弃.likarnet.com通配符格式,需改为['likarnet.com', 'www.likarnet.com'],或用*临时测试(生产环境禁用)。
    • 重启Gunicorn服务:sudo systemctl restart gunicorn,避免配置未加载。
  2. 修正Nginx代理头配置

    • 当前proxy_set_header Host $host;会传递请求的原始Host头,若直接访问localhost:80会导致Host为localhost,建议替换为proxy_set_header Host $server_name;,强制传递配置的域名作为Host头,确保Django收到的Host在ALLOWED_HOSTS列表内。
    • 重启Nginx并验证配置:sudo nginx -t && sudo systemctl restart nginx。
  3. 检查Gunicorn Socket权限

    • 执行ls -l /run/gunicorn.sock查看权限,确保Nginx用户(通常为www-data)可读写。若权限不足,可修改Gunicorn配置添加--user www-data --group www-data,或临时调整socket权限:sudo chmod 777 /run/gunicorn.sock(生产环境建议用更严格的权限)。
  4. 验证SSL与防火墙配置

    • 检查是否存在监听443端口的Nginx server块,确保SSL证书配置正确。若SSL配置缺失或错误,会导致外部访问被拒绝。
    • 检查防火墙状态:sudo ufw status,确保80、443端口已开放,若未开放执行:sudo ufw allow 80/tcp && sudo ufw allow 443/tcp。
  5. 直接测试Gunicorn的Host处理

    • 绑定TCP端口启动Gunicorn:/home/likarnet/venv/bin/gunicorn --bind 127.0.0.1:8001 likarnet.wsgi:application,然后执行curl -H "Host: likarnet.com" localhost:8001,若返回正常,说明问题出在Nginx代理或Socket配置。

内容的提问来源于stack exchange,提问作者Mykhaylo Chornenkyy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:08:11