我花了几个小时试图弄清楚这一点并寻找答案,但似乎找不到让事情正常运作的方法。
基本上,我想使用 Nginx 作为我的 docker 设置的反向代理。这很简单。这是我的配置,下面我将解释我的问题。
server {
server_name ~^(.*)$;
resolver 127.0.0.11;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_header Server;
location / {
proxy_pass $scheme://$1;
error_page 500 502 = @catch;
}
location @catch {
proxy_pass $scheme://apache;
}
}
所以我的问题在于。如果第一个位置不存在,我希望位置 @catch 可以作为后备。以下是一个例子:
假设我想打开网站foo.com
。如果foo.com
可以访问,则返回的所有内容都应由 Nginx 返回。但如果foo.com
无法访问,我想捕获错误页面并改为调用位置 @catch。
我知道我可以添加proxy_intercept_errors on
,但如果foo.com
返回 500 页,该页面也会被“捕获”,我不希望发生这种情况。
我只想在 URL 无法访问时捕获 Nginx 生成的错误页面。
有人能帮助我吗?
谢谢。
编辑:我会尝试更好地解释我正在做什么以及我的问题是什么。
我有一个运行 Nginx 的容器,它什么也不做,只是充当反向代理并将请求传递给相应的容器。我有一个名为的容器apache
,如果没有可用的 docker 容器并以请求的域作为容器名称,它将充当后备容器。
示例:有 3 个容器正在运行,它们的名称如下:
nginx
apache
foo.com
现在容器nginx
收到一个请求foo.com
,该请求应该被传递给该容器。如果 apache 返回 500 错误,则应该将该错误消息发送给客户端。
但是如果nginx
收到 的请求bar.baz
,nginx 将找不到具有该名称的容器并产生自己的 500 或 502 错误。只有在这种情况下,我才想将请求传递给容器apache
。但是如果apache
容器现在返回代码为 500 的错误,则应将此错误传递给客户端。
长话短说:我需要一种方法来捕获在 Nginx 中或由 Nginx 产生的错误,但如果这些错误来自后端则不需要。
答案1
我刚刚发现为什么它没有按预期工作。我在 docker 容器中使用 Nginx,它会自动使用主机系统中的 hosts 文件。
我的 server_name 指令采用的是整个主机名(如foo.com
)。在我的 hosts 文件中,我重定向foo.com
到127.0.0.1
。现在,如果我的配置使用完整主机名(foo.com
在本例中),它将“找到”相应的 IP。所以我稍微更改了我的配置,如下所示:
server {
server_name ~^(?<domain>.*)(\..*)$;
resolver 127.0.0.11;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_header Server;
location / {
proxy_pass $scheme://$domain;
error_page 500 502 = @catch;
}
location @catch {
proxy_pass $scheme://apache;
}
}
现在 Nginx 将寻找名为foo
而不是 的容器foo.com
。如果没有名为 的容器,foo
此操作将按预期失败,并由位置进行处理@catch
。