我们在Docker的常用域下有几个rails应用程序,我们使用nginx将请求定向到特定应用程序。
our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar
Config看起来像这样:
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
我们不需要它们全部启动但是nginx失败了。 如何让nginx忽略失败的上游?
答案 0 :(得分:64)
如果您可以使用静态IP,那么只需使用它,它就会启动,如果没有响应则返回503
。
使用resolver
指令指向可以解析主机的内容,无论它是否正在运行。
如果您无法执行上述(这将允许Nginx启动/运行),则在location
级别解析它:
location /foo {
resolver 127.0.0.1 valid=30s;
# or some other DNS (you company/internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.1 valid=30s;
# or some other DNS (you company/internal DNS server)
#resolver 8.8.8.8 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
答案 1 :(得分:11)
使用upstream
的主要优点是定义一组服务器,而不是可以在不同端口上侦听,并在它们之间配置负载平衡和故障转移 即可。
在您的情况下,您每个上游仅定义1个主服务器,因此必须为 。
相反,请为proxy_pass
使用变量,并记住处理目标服务器关闭时可能出现的错误(404s,503s)。
答案 2 :(得分:2)
对我来说,@ Justin / @ duskwuff的答案的选项3解决了该问题,但是我不得不将解析器IP更改为 127.0.0.11 (Docker的DNS服务器):
location /foo {
resolver 127.0.0.11 valid=30s;
set $upstream_foo foo;
proxy_pass http://$upstream_foo:80;
}
location /bar {
resolver 127.0.0.11 valid=30s;
set $upstream_bar foo;
proxy_pass http://$upstream_bar:80;
}
但是正如@ Justin / @ duskwuff所述,您可以使用任何其他外部DNS服务器。
答案 3 :(得分:1)
针对某人场景的另一个快速简便的修复方法,我可以启动和停止,而我的主服务器不会被炸毁
extra_hosts:
- "dockerhost:172.20.0.1" # <-- static ipv4 gateway of the network ip here thats the only sorta downside but it works for me, you can ifconfig inside a container with the network to find yours, kinda a noob answer but it helped me
networks:
- my_network
server {
listen 80;
server_name servername;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass https://dockerhost:12345;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
答案 4 :(得分:0)
我遇到了同样的“找不到主机”问题,因为部分主机是使用$uri
而不是$request_uri
映射的:
proxy_pass http://one-api-service.$kubernetes:8091/auth;
当请求更改为auth子请求时,$uri
失去了初始值。将映射更改为使用$request_uri
而不是$uri
解决了我的问题:
map $request_uri $kubernetes {
# ...
}
答案 5 :(得分:-7)
您不能使用--link
选项,而是可以使用端口映射并将nginx绑定到主机地址。
示例:使用-p 180:80
选项运行第一个泊坞窗容器,使用-p 280:80
选项运行第二个容器。
运行nginx并为代理设置这些地址:
proxy_pass http://192.168.1.20:180/; # first container
proxy_pass http://192.168.1.20:280/; # second container