2015-09-29 40 views
48

Mamy kilka aplikacji railsowych pod wspólną domeną w Docker, a my używamy nginx do kierowania żądań do konkretnych aplikacji.Konfiguracja nginx, aby się nie zawieść, jeśli nie znaleziono hosta w poprzedniej wersji

our_dev_server.com/foo # proxies to foo app 
our_dev_server.com/bar # proxies to bar 

Config wygląda następująco:

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... 
} 

Jeśli jedna z tych aplikacji nie jest uruchamiany wtedy nginx nie powiedzie się i zatrzymuje:

host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6 

Nie musimy ich wszystkich zmajstrować ale nginx nie może inaczej. Jak zmusić nginx do ignorowania niepowodzeń?

+0

Czy łączenie pojemników aplikacji z pojemników nginx lub uruchamiając je oddzielić od siebie? Jeśli host w bloku 'upstream' nie zostanie rozwiązany, w czasie wykonywania, Nginx zakończy działanie z powyższym błędem ... – Justin

+0

Jeśli możesz użyć adresu IP, to uruchomi się dobrze. Czy w twoim przypadku działałoby 'resolver' (http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver)? – Justin

+0

@Justin mamy każdej aplikacji w osobnym pojemniku, nginx też. Połącz je z dokowaniem –

Odpowiedz

39
  1. Jeśli można użyć statycznego adresu IP, a następnie po prostu użyć, że będzie to starcie i po prostu wrócić 503 „s, jeśli nie reaguje.

  2. Skorzystaj z dyrektywy resolver, aby wskazać coś, co może rozwiązać hosta, niezależnie od tego, czy aktualnie jest włączony, czy nie.

  3. go rozwiązać na poziomie location, jeśli nie można zrobić wyżej (pozwoli to Nginx do Start/Uruchom):

    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

Twoja opcja 3 działa doskonale dla mnie. Jeśli nie określę resolwera, czy wiesz, jak długo nginx będzie buforował IP, który rozwiązuje? –

+3

Dzięki! Po prostu użycie zmiennej wydaje się powstrzymywać nginx przed byciem inteligentnym. – Blanka

+0

Zauważyłem, że grupa przechwytująca regex pozwoliła mi pominąć zmienną: 'location ~ ^/foo /(.*)$ {proxy_pass http: // foo/$ 1; } ' –

4

Główną zaletą korzystania upstream jest aby zdefiniować grupę serwerów niż można nasłuchiwać na różnych portach i skonfigurować równoważenie obciążenia i przełączanie awaryjne między nimi.

W twoim przypadku masz tylko zdefiniowanie 1 podstawowy serwer za upstream tak to musi być na.

Zamiast tego użyj zmiennych dla swojego proxy_pass (s) i pamiętaj, aby obsłużyć możliwe błędy (404, 503), które możesz uzyskać, gdy serwer docelowy nie działa.

-4

Nie można użyć opcji --link, zamiast tego można użyć mapowania portów i powiązać nginx z adresem hosta.

Przykład: Uruchom swój pierwszy kontener dokera z opcją -p 180:80, drugi pojemnik z opcją -p 280:80.

Run nginx i ustawić te adresy proxy:

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

co zrobić, jeśli dynamicznie utworzyć ich sieć? – EralpB