Linode Ubuntu环境下Flask/Nginx配置问题:www子域名500错误
解决www.domain.com访问500错误(重定向循环)
问题背景
在Linode计算实例上部署了基于Flask/Nginx/Gunicorn/Supervisor的简易微博站点,主域名domain.com可正常访问,但访问www.domain.com时出现500错误,Nginx日志提示如下:
rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 2603:7000:a700:cc1:c867:5aae:ff32:199c, server: www.domain.com, request: "GET / HTTP/1.1", host: "www.domain.com"
当前生效的Nginx配置:
server { server_name domain.com www.domain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = domain.com) { return 301 https://$host$request_uri; } # managed by Certbot listen [::]:80; listen 80; server_name domain.com; return 404; # managed by Certbot }
问题原因
- Flask主机名限制:Flask应用未配置允许
www.domain.com作为请求Host头,当Nginx将www.domain.com的请求代理到Gunicorn时,Flask直接返回500错误。 - Nginx错误页循环:Certbot生成的
options-ssl-nginx.conf文件中默认包含error_page规则,会将500错误重定向到/index.html;而/index.html又会被Nginx代理回Flask,Flask再次返回500,形成无限循环。 - HTTP跳转缺失:80端口的Nginx配置未处理
www.domain.com的HTTP请求,导致http://www.domain.com直接返回404,影响访问体验。
解决步骤
步骤1:修改Flask配置,允许www域名
在Flask应用的配置代码中,将www.domain.com添加到允许的主机列表:
# 推荐方式:使用ALLOWED_HOSTS app.config['ALLOWED_HOSTS'] = ['domain.com', 'www.domain.com'] # 备选方式:若使用SERVER_NAME(注意:会影响路由和子域名解析,需谨慎) # app.config['SERVER_NAME'] = 'domain.com'
修改完成后,重启Supervisor或Gunicorn使配置生效。
步骤2:修复Nginx的HTTP跳转配置
更新80端口的server块,添加www.domain.com的HTTP到HTTPS跳转规则:
server { if ($host = domain.com) { return 301 https://$host$request_uri; } # managed by Certbot # 添加www域名的HTTP跳转规则 if ($host = www.domain.com) { return 301 https://$host$request_uri; } listen [::]:80; listen 80; server_name domain.com www.domain.com; # 更新server_name包含www域名 return 404; # managed by Certbot }
步骤3:验证配置并重启Nginx
先检查Nginx配置语法是否正确:
sudo nginx -t
确认无错误后,重启Nginx:
sudo systemctl restart nginx
内容的提问来源于stack exchange,提问作者goon
相关产品推荐
相关产品推荐

