我们在Docker的公共域下有几个rails应用程序,我们使用nginx将请求定向到特定的应用程序。
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
配置如下所示:
upstream foo {
server foo:3000;
}
upstream bar {
server bar:3000;
}
# and about 10 more...
server {
listen *:80 default_server;
server_name our_dev_server.com;
location /foo {
# this is specific to asset management in rails dev
rewrite ^/foo/assets(/.*)$ /assets/$1 break;
rewrite ^/foo(/.*)$ /foo/$1 break;
proxy_pass http://foo;
}
location /bar {
rewrite ^/bar/assets(/.*)$ /assets/$1 break;
rewrite ^/bar(/.*)$ /bar/$1 break;
proxy_pass http://bar;
}
# and about 10 more...
}
如果其中一个应用程序没有启动,那么nginx将失败并停止:
host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6
我们不需要它们都是up的,但是nginx会失败。如何让nginx忽略失败的上游?
9条答案
按热度按时间ctzwtxfj1#
1.如果你可以使用一个静态IP,那么就使用它,它会启动,如果它没有响应,就返回
503
。1.使用
resolver
指令指向可以解析主机的内容,而不管主机当前是否已启动。1.解决它在
location
级别,如果你不能做到以上 (这将允许Nginx启动/运行):w8ntj3qf2#
对我来说,@Justin/@duskwuff的答案中的选项3解决了这个问题,但我不得不将解析器IP更改为127.0.0.11(Docker的DNS服务器):
但是正如@Justin/@duskwuff提到的,您可以使用任何其他外部DNS服务器。
brjng4g33#
使用
upstream
的主要优点是定义一组服务器,它们可以监听不同的端口并在它们之间配置负载平衡和故障转移***。在您的情况下,您仅为每个上游定义了1个主服务器,因此 * 它必须启动**。
相反,对
proxy_pass
使用变量,并记住处理目标服务器关闭时可能出现的错误(404s、503s)。使用变量的示例:
zbq4xfa04#
我们遇到了一个类似的问题,我们通过动态地将conf文件包含在上游容器中来解决它,这些文件是由一个对docker.sock上的事件做出React的side-car容器生成的,并且在上游配置中使用通配符来包含这些文件:
如果列表是空的,我们添加了一个永久关闭的服务器条目-所以有效的服务器列表不是空的。
最后一个条目指向Nginx中托管错误页面的(内部)服务器(例如503)
最终的上游配置如下所示:
}
在nginx配置中,我们添加了一个侦听错误端口的服务器:
如前所述,每个上游容器的配置文件都是由一个脚本(bash、curl、jq)生成的,该脚本使用curl和它的rest api与docker.socket交互,以获取所需的信息(ip、port),并使用此模板生成文件。
lh80um4z5#
另一个快速和简单的修复某人的情况下,我可以开始和停止没有我的主服务器爆炸了
hfsqlsce6#
我遇到了同样的“Host not found”问题,因为我的主机的一部分是使用
$uri
而不是$request_uri
Map的:当请求更改为auth子请求时,
$uri
丢失了初始值。将Map更改为使用$request_uri
而不是$uri
解决了我的问题:2eafrhcq7#
根据Justin的回答,最快的方法是用IP地址替换最后一个主机。你需要用
--ip 172.18.0.XXX
参数为每个容器分配一个静态IP地址。NGINX不会在启动时崩溃,如果主机不可用,它只会以502错误响应。使用静态IP运行容器:
Nginx配置:
请参阅this帖子如何使用Docker设置子网。
cx6n0qe38#
https://stackoverflow.com/a/32846603/11780117
我不能添加评论,所以我在这里添加。
如果原始反向代理是这样编写的:
当用户访问
https://you-domain/api/test?query=name
URL时,后端服务器收到的PATH是/api/test?query=name
,它正在工作。请注意,这里当您请求
https://you-domain/api/test?query=name
URL时,后端服务器实际接收到的PATH是/api
,它丢失了许多参数。因此,当您使用变量时,正确的配置应该是:
如果你想访问根目录的代理访问后端,那么你需要这个:
然后您请求
https://you-domain/api/test?query=name
,后端服务器实际收到的PATH是/test?query=name
。vcudknz39#
您可以不使用
--link
选项,而是使用端口Map并将nginx绑定到主机地址。示例:使用
-p 180:80
选项运行第一个Docker容器,使用-p 280:80
选项运行第二个容器。运行nginx并为代理设置以下地址: