Не могу найти решения для, казалось бы, тривиальной ситуации. Есть несколько контейнеров-приложений, которые проксирует nginx — классическая схема. В решении возможна ситуация, когда те или иные приложения будут простаивать отключенными. В принципе, это тоже должна быть распространенная ситуация (например, когда приложение находится на обслуживании или в процессе разработки). Речь не об определенном времени, понятно, что на некоторое время можно сохранить ожидание nginx и использовать backup-сервер, если отключение происходит во время работы nginx. Вот пример условной конфигурации:
upstream server_1 {
server app_1:10;
}
upstream server_2 {
server app_2:20;
# можно задать разные опции, ожидание, количество попыток и даже backup-сервер, не принципиально
}
# ... еще некоторые приложения
server {
# ... пропускаю типовую конфигурацию, она рабочая
location /server_1 {
proxy_pass http://server_1;
# ... заголовки и прочее
}
location /server_2 {
proxy_pass http://server_2;
}
# ... еще сколько-то точек входа
# можно попробовать и такой вариант, без upstream, итог не меняется:
location /server_N {
proxy_pass http://app_N:100;
}
}
В любом случае, если мы отключили, вывели на какое-то время, например, приложение
app_1, nginx вылетит с ошибкой на запуске или в процессе:
host not found in upstream app_1
Я нашел одно гипотетическое решение: использовать статические IP-адреса вместо сетевых имен Docker, скажем, установить для app_1 заведомо определенный
ipv4_address: 172.18.0.2, плюс, некий maintenance-сервис как backup в upstream, скажем, еще копия nginx, возвращающая 503-й статус:
upstream server_1 {
server 172.18.0.2:10;
server mainetnance:500 backup;
}
— но это некрасиво и неверно (к примеру, подозреваю проблемы с масштабированием, если нужно будет размножить app_1).
Есть ли какие-то решения? Мне думается, упускаю из вида что-то очевидное.
Сергей Соколов приводит решение в случае proxy_pass с определением переменной, в которой будет храниться хост, nginx, в этом случае, по какой-то причине не проверяет значение:
set $srv1 = http://app1:10;
...
proxy_pass $srv1;