2015-09-29 1 views
48

У нас есть несколько рельсовых приложений под общим доменом в Docker, и мы используем nginx для прямых запросов к конкретным приложениям.Настройка 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 ignore неудачным вверх по течению?

+0

Вы связывающая приложение контейнеры с контейнерами Nginx, или работает их отдельно друг от друга? Если хост в блоке 'upstream' не будет разрешен, во время выполнения Nginx выйдет с указанной выше ошибкой ... – Justin

+0

Если вы можете использовать IP-адрес, тогда он будет запущен в порядке. Использует ли 'resolver' (http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver) работу в вашем случае? – Justin

+0

@ У нас есть каждое приложение в отдельном контейнере, nginx тоже. Свяжите их с докером. –

ответ

39
  1. Если вы можете использовать статический IP-адрес, то просто использовать, что это будет запуск и просто вернуть 503 «S, если он не отвечает.

  2. Используйте директиву resolver, чтобы указать на то, что может разрешить хост, независимо от того, в настоящий момент оно или нет.

  3. Решимость его на location уровне, если вы не можете сделать выше (это позволит Nginx для запуска/запуска):

    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; 
    } 
    
+0

ваш вариант 3 отлично подходит для меня. Если я не укажу resolver, знаете ли вы, как долго nginx будет кэшировать IP-адрес, который он разрешает? –

+3

Спасибо! Просто использование переменной, похоже, не позволяет nginx быть умным. – Blanka

+0

Я обнаружил, что группа захвата регулярных выражений позволила мне пропустить переменную: 'location ~ ^/foo /(.*)$ {proxy_pass http: // foo/$ 1; } ' –

4

Основное преимущество использования upstream является определить группу серверов, чем можно прослушивать на разных портах, а также настроить балансировку нагрузки и отказоустойчивость между ними.

В вашем случае вы только определение 1 первичного сервера на входе так он должен быть до.

Вместо этого используйте переменные для своих proxy_pass и не забудьте обработать возможные ошибки (404s, 503s), которые вы можете получить, когда целевой сервер не работает.

-4

Вы можете не использовать опцию --link, вместо этого вы можете использовать сопоставление портов и связывать nginx с адресом хоста.

Пример: Запустите свой первый контейнер-докер с опцией -p 180:80, второй контейнер с опцией -p 280:80.

Run Nginx и установить эти адреса для прокси-сервера:

proxy_pass http://192.168.1.20:180/; # first container 
proxy_pass http://192.168.1.20:280/; # second container 
+0

Что делать, если динамически создавать сеть из них? – EralpB

Смежные вопросы