使用 nginx 在 Django ALLOWED_HOSTS 中处理动态 IP
Handling dynamic IP in Django ALLOWED_HOSTS with nginx
我认为我的 nginx.conf 有问题,这导致实例一次又一次地重新启动,因为我的托管容器服务的运行状况检查失败。
我正在 运行在 AWS Lightsail 容器中设置我的设置,其中我有三个容器 运行宁:
- nginx
- django
- nextjs
在我的 AWS Lightsail 实例上发布新版本时 运行 几分钟没问题,然后我遇到 503 错误,导致实例重启 - 运行 几分钟然后重新启动。
查看日志我可以看到健康检查失败,django 抛出错误提示我应该将请求 IP 添加到允许的主机:
[28/Aug/2021:13:56:23] Invalid HTTP_HOST header: 'x.x.x.x'. You may need to add 'x.x.x.x' to ALLOWED_HOSTS.
[28/Aug/2021:13:56:23] Bad Request: /health.txt
问题是我的 lightsail 容器服务没有静态 IP(我也不相信我可以获得静态 IP)。
我目前的 nginx.conf 低于(感谢反馈)。 我的问题这里是我应该如何处理这个问题?我觉得设置 ALLOWED_HOSTS = ['*']
不是一个好方法。我可以对主机进行硬编码以进行健康检查或类似检查吗?
nginx.conf:
upstream backend {
server ${BACKEND_HOST}:${BACKEND_PORT};
}
upstream frontend {
server ${FRONTEND_HOST}:${FRONTEND_PORT};
}
server {
listen 80 default_server;
server_name example.com;
server_tokens off;
gzip on;
gzip_proxied any;
gzip_comp_level 4;
gzip_types text/css application/javascript image/svg+xml;
location /robots.txt {
include proxy_params;
proxy_pass http://backend;
}
location /health.txt {
include proxy_params;
proxy_pass http://backend;
}
location /api {
include proxy_params;
proxy_pass http://backend;
}
location /admin {
include proxy_params;
proxy_pass http://backend;
}
location / {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
我使用 AWS EC2,为了通过健康检查,我动态获取实例的 ip,然后将其插入 ALLOWED_HOSTS(我认为它也适用于 Lightsail 容器):
import requests
def get_instance_ip():
try:
ip = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4').text
except requests.exceptions.ConnectionError:
return None
return ip
AWS_IP = get_ec2_instance_ip()
if AWS_IP is not None:
ALLOWED_HOSTS += [AWS_IP]
您还可以创建一个中间件,该中间件始终 returns 健康检查使用的路径的 200 状态代码(在 MIDDLEWARE
中的 django.middleware.security.SecurityMiddleware
之前插入自定义中间件以避免 Invalid HTTP_HOST header
错误)。
我认为我的 nginx.conf 有问题,这导致实例一次又一次地重新启动,因为我的托管容器服务的运行状况检查失败。
我正在 运行在 AWS Lightsail 容器中设置我的设置,其中我有三个容器 运行宁:
- nginx
- django
- nextjs
在我的 AWS Lightsail 实例上发布新版本时 运行 几分钟没问题,然后我遇到 503 错误,导致实例重启 - 运行 几分钟然后重新启动。
查看日志我可以看到健康检查失败,django 抛出错误提示我应该将请求 IP 添加到允许的主机:
[28/Aug/2021:13:56:23] Invalid HTTP_HOST header: 'x.x.x.x'. You may need to add 'x.x.x.x' to ALLOWED_HOSTS.
[28/Aug/2021:13:56:23] Bad Request: /health.txt
问题是我的 lightsail 容器服务没有静态 IP(我也不相信我可以获得静态 IP)。
我目前的 nginx.conf 低于(感谢反馈)。 我的问题这里是我应该如何处理这个问题?我觉得设置 ALLOWED_HOSTS = ['*']
不是一个好方法。我可以对主机进行硬编码以进行健康检查或类似检查吗?
nginx.conf:
upstream backend {
server ${BACKEND_HOST}:${BACKEND_PORT};
}
upstream frontend {
server ${FRONTEND_HOST}:${FRONTEND_PORT};
}
server {
listen 80 default_server;
server_name example.com;
server_tokens off;
gzip on;
gzip_proxied any;
gzip_comp_level 4;
gzip_types text/css application/javascript image/svg+xml;
location /robots.txt {
include proxy_params;
proxy_pass http://backend;
}
location /health.txt {
include proxy_params;
proxy_pass http://backend;
}
location /api {
include proxy_params;
proxy_pass http://backend;
}
location /admin {
include proxy_params;
proxy_pass http://backend;
}
location / {
proxy_pass http://frontend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
我使用 AWS EC2,为了通过健康检查,我动态获取实例的 ip,然后将其插入 ALLOWED_HOSTS(我认为它也适用于 Lightsail 容器):
import requests
def get_instance_ip():
try:
ip = requests.get('http://169.254.169.254/latest/meta-data/local-ipv4').text
except requests.exceptions.ConnectionError:
return None
return ip
AWS_IP = get_ec2_instance_ip()
if AWS_IP is not None:
ALLOWED_HOSTS += [AWS_IP]
您还可以创建一个中间件,该中间件始终 returns 健康检查使用的路径的 200 状态代码(在 MIDDLEWARE
中的 django.middleware.security.SecurityMiddleware
之前插入自定义中间件以避免 Invalid HTTP_HOST header
错误)。