Ana makine bağlantı noktası! = Konteyner bağlantı noktası olduğunda Nginx docker makinesinde yeniden yazma


10

Tüm bağlantı noktası 80 üzerinde dinleme nginx çalışan birden fazla liman işçisi çalıştırmaya çalışıyorum, ancak farklı bağlantı noktası bağlantı noktaları kapsayıcı bağlantı noktası 80 eşleme ile.

Çoğunlukla bu, nginx'in bir eğik çizgi eksik olması nedeniyle bir yönlendirme yapması dışında çalışır.

server {
    listen 80;
    root /var/www;
    index index.html;
    location /docs {}
}

Yukarıdaki nginx yapılandırma ve 8080 konteyner bağlantı noktasına eşlenmiş ana bağlantı noktası 8080 ile çalışan bir docker konteyner göz önüne alındığında localhost alabilirsiniz: 8080 / docs / curl ok yoluyla:

> GET /docs/ HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
* Server nginx/1.9.5 is not blacklisted
< Server: nginx/1.9.5
< Date: Sat, 28 Nov 2015 17:27:05 GMT
< Content-Type: text/html
< Content-Length: 6431
< Last-Modified: Sat, 28 Nov 2015 17:17:06 GMT
< Connection: keep-alive
< ETag: "5659e192-191f"
< Accept-Ranges: bytes
<
... html page ...

ancak localhost istersem: 8080 / docs localhost / docs /

> GET /docs HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
* Server nginx/1.9.5 is not blacklisted
< Server: nginx/1.9.5
< Date: Sat, 28 Nov 2015 17:29:40 GMT
< Content-Type: text/html
< Content-Length: 184
< Location: http://localhost/docs/
< Connection: keep-alive
<
... html redirect page ...

Yönlendirme yaparken orijinal bağlantı noktasını korumak için nginx'i nasıl alabilirim? Port_in_redirect ve sunucu_adı_in_redirect bakarak denedim ama onlar yardımcı olmadı.


DÜZENLE

Https://forum.nginx.org/read.php?2,261216,261216#msg-261216 temel alınarak bu şu anda mümkün görünmüyor.


İçine bak nginx-vekil Eğer bu deli liman yeniden yazma önemsiz birini yapmak zorunda kalmamak, konteyner.
Michael Hampton

Bu kapların önünde hiçbir şey dengelemek istemiyorum. Ben bir env var dayalı harici port ayarlar bir docker-compose dosyası var ve çoğu zaman ben sadece "docker-compose up -d" bu dosya bir kez. Ancak test nedenleriyle ve diğer şeyler üzerinde çalışmama izin vermek için, yeni bir konteyner kümesini (yeni proje adı nedeniyle) döndürmek için "PORT = 8080 docker-compose -p test up -d" yapmak istiyorum. ) farklı bir ana makine bağlantı noktasıyla eşleştirilir.
Ibasa

Ack, bu problemle de karşılaştım. Sanırım vanilya nginx'e gitmem ya da 8080'deki eşyaları başka bir şeye taşımam gerekecek.
Ken

Yanıtlar:


2

En basit çözüm, indexyönergeyi kaldırmak ve açık veya kapalı $uri/yönlendirmelere güvenmemek . Örneğin:

server {
  listen 80;
  root /var/www;
  location /docs {
    try_files $uri $uri/index.html =404;
  }
}

Yönlendirmeyi tamamen önlediğinden bu aynı davranış değildir. Dizin modülünün verdiği gibi bir eğik çizgi yönlendirmesi istiyorsanız, daha karmaşık bir çözüm gerekir. Örneğin:

server {
  listen 80;
  root /var/www;
  location /docs {
    try_files $uri @redirect;
  }
  location @redirect {
    if ($uri ~* ^(.+)/$) { rewrite ^ $uri/index.html last; }
    if (-d $document_root$uri) { return $scheme://$host:8080$uri/; }
    return 404;
  }
}

Bunu denedim soruda söylediğim gibi, ben port_in_redirect kapalı ekledi; http bloğuna, localhost / docs / 'a yönlendirmenin aynı sonucu olarak server_name_in_redirect eklemeyi denedi; de. Hala localhost / docs /
Ibasa'ya

@Ibasa Evet, bunun için üzgünüm. İki kez okuyun - bir kez yazın. Bunu hatırlamaya çalışmalıyım.
Richard Smith

5

HTTP istemcileri bağlantı noktasını Ana Bilgisayar üstbilgisine koyar. Yönlendirme yaparken ana bilgisayar üstbilgisinin orijinal değerini kullanırsanız, beklendiği gibi çalışması gerekir. Aşağıdaki kodu test ettim ve tam olarak ne istediğini yapıyor gibi görünüyor:

location ~ ^.*[^/]$ {
    try_files $uri @rewrite;
}
location @rewrite {
    return 302 $scheme://$http_host$uri/;
}

> GET /bla HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Server: nginx/1.9.7
< Date: Sun, 29 Nov 2015 06:23:35 GMT
< Content-Type: text/html
< Content-Length: 160
< Connection: keep-alive
< Location: http://localhost:8080/bla/

Bu teknik olarak doğru cevaptır. IP'lerle de çalışır, örneğin 127.0.0.1:8000 isteğinde http_host olarak 127.0.0.1:8000 bulunur. Bunun nedeni şu şekildedir : tools.ietf.org/html/rfc2616#section-14.23 http_host, bir limanın ekleneceği belirsizliğe hitap etmelidir. Bağlantı noktaları dışarıda bırakılırsa, varsayılanlar ima edilir (örneğin, 80 veya 443). Bu çözüm, çalışmak için en temiz çözüm olmalı ...
lifeofguenter

0

Sadece bu basit düzeltmeyi takip edin

location /app {
    alias /usr/share/nginx/html/folder;
    if (-d $request_filename) {
        rewrite [^/]$ $scheme://$http_host$uri/ permanent;
    }
}

0

İlginç ... Bu sorunla tam olarak karşılaştım ve Richard Smith'in cevabının önerdiği gibi bunu düzelttim :

root /var/www;
location = /docs {
    try_files $uri $uri/ =404;
}

Tek fark, belirtmem index.html?

Yeniden yönlendirme döngüsünü önlemek için hata kodunu belirtin.

Hala nginx'in desteğinden geribildirim bekliyorum.


0

Docker'ınız nginx konteynerinize bir çeşit NAT / Proxy olduğu için olduğunu düşünüyorum. Farklı bağlantı noktası ekleme işlemleri için yönlendirme bilgisi gereklidir.

Benim için bu çözüldü nginx.conf için aşağıdakileri ekleyin

http {
    ...
    proxy_set_header Host $http_host; # required for docker client's sake
    proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    ...
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.