Estoy tratando de ejecutar múltiples contenedores docker, todos ejecutando nginx escuchando en el puerto 80, pero con diferentes puertos de host que se asignan al puerto 80 de los contenedores.
En su mayor parte, esto funciona, excepto cuando nginx realiza una redirección debido a la falta de una barra diagonal final.
server { listen 80; root /var/www; index index.html; location /docs {}}
Dada la configuración de nginx anterior y un contenedor de docker que lo ejecuta con el puerto de host 8080 asignado al puerto de contenedor 80, puedo obtener localhost: 8080 / docs / a través de curl ok:
> 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 ...
pero si solicito localhost: 8080 / docs, obtengo una redirección a 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 ...
¿Cómo puedo hacer que nginx conserve el puerto original al hacer la redirección? Intenté mirar port_in_redirect y server_name_in_redirect pero no ayudaron.
Los clientes HTTP colocarán el puerto en el encabezado del Host. Si utiliza el valor original del encabezado host al realizar la redirección, debería funcionar como se esperaba. Probé el siguiente código y parece estar haciendo exactamente lo que solicitó:
Este no es un comportamiento idéntico, ya que evita la redirección por completo. Si desea una redirección de barra diagonal final como la que proporciona el módulo index, se requiere una solución más compleja. Por ejemplo:
Creo que sucede ya que su Docker es una especie de NAT/Proxy para su contenedor nginx. Para el enrutamiento entre diferentes puertos se requiere información de adición.
Para mí esto se resolvió agregue lo siguiente al nginx.conf
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; ...}
Realmente no quiero que nada se balancee frente a estos contenedores. Tengo un archivo docker-compose que establece el puerto externo en función de una var env, y la mayoría de las veces solo “docker-compose up-d” este archivo una vez. Sin embargo, por razones de prueba y para permitirme trabajar en otras cosas, quiero poder hacer “PORT=8080 docker-compose-p test up-d” para activar un conjunto completamente nuevo de contenedores (debido al nuevo nombre del proyecto) que se asignan a un puerto host diferente.