У нас есть несколько приложений rails под общим доменом в Docker, и мы используем 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
Нам не нужно, чтобы они все работали, но в противном случае nginx выйдет из строя. Как заставить nginx игнорировать неудачные апстримы?
nginx
url-rewriting
proxypass
Морозов
источник
источник
upstream
блоке не разрешается во время выполнения, Nginx завершит работу с указанной выше ошибкой ...resolver
( nginx.org/en/docs/http/ngx_http_core_module.html#resolver )?proxy.sh
скрипт, который считывает переменные среды и динамически добавляетupstream
записи для каждой, а затем запускает Nginx. Это прекрасно работает в том смысле, что, когда мы запускаем наш прокси-контейнер, мы можем передавать необходимые восходящие потоки во время выполнения. Вы могли бы сделать что-то подобное, чтобы включить / отключить определенные восходящие потоки при запуске (или, как моя установка, просто добавьте те, которые нужны во время выполнения)Ответы:
Если вы можете использовать статический IP-адрес, просто используйте его, он запустится и просто вернет
503
, если не ответит.Используйте
resolver
директиву, чтобы указать на что-то, что может разрешить хост, независимо от того, работает он в данный момент или нет.Разрешите это на
location
уровне, если вы не можете сделать это (это позволит запускать / запускать Nginx) :источник
location ~ ^/foo/(.*)$ { proxy_pass http://foo/$1; }
Для меня вариант 3 ответа от @ Justin / @ duskwuff решил проблему, но мне пришлось изменить IP-адрес преобразователя на 127.0.0.11 (DNS-сервер Docker):
Но, как упоминал @ Justin / @ duskwuff, вы можете использовать любой другой внешний DNS-сервер.
источник
Основным преимуществом использования
upstream
является определение группы серверов, которые могут прослушивать разные порты и настраивать балансировку нагрузки и аварийное переключение. между ними. .В вашем случае вы определяете только 1 первичный сервер для каждого восходящего потока, поэтому он должен быть включен .
Вместо этого используйте переменные для своих
proxy_pass
(ов) и не забудьте обработать возможные ошибки (404, 503), которые могут возникнуть, когда целевой сервер не работает.источник
set $variable http://foo
иproxy_pass $variable
сохраню foo «вверх по течению» (чтобы сохранить упомянутые вами преимущества), то я все равно столкнусь с проблемой, упомянутой OP.set $variable foo
иproxy_pass http://$variable
У меня была та же проблема «Хост не найден», потому что часть моего хоста отображалась с использованием
$uri
вместо$request_uri
:И когда запрос изменился на подзапрос auth, он
$uri
потерял свое первоначальное значение. Изменение сопоставления для использования$request_uri
вместо$uri
решения моей проблемы:источник
Вы можете не использовать
--link
опцию, вместо этого вы можете использовать сопоставление портов и привязать nginx к адресу хоста.Пример: запустите свой первый контейнер докеров с
-p 180:80
опцией, второй контейнер с-p 280:80
опцией.Запустите nginx и установите эти адреса для прокси:
источник