¿Cómo configurar la asignación del puerto de Docker para usar Nginx como un proxy ascendente?


Answers

Usando los enlaces de acoplador , puede vincular el contenedor de aguas arriba al contenedor de nginx. Una característica adicional es que Docker administra el archivo de host, lo que significa que podrá referirse al contenedor vinculado usando un nombre en lugar de la IP potencialmente aleatoria.

Question

Actualización II

Ahora es 16 de julio de 2015 y las cosas han cambiado nuevamente. Descubrí este contenedor automágico de Jason Wilder : https://github.com/jwilder/nginx-proxy y resuelve este problema casi tanto como demora docker run el contenedor. Esta es ahora la solución que estoy usando para resolver este problema.

Actualizar

Ahora es julio de 2015 y las cosas han cambiado drásticamente con respecto a los contenedores Docker de redes. Ahora hay muchas ofertas diferentes que resuelven este problema (en una variedad de formas).

Deberías usar esta publicación para obtener una comprensión básica de la aplicación docker --link enfoque de docker --link para la detección de servicios, que es lo más básico posible, funciona muy bien y, en realidad, requiere menos baile elegante que la mayoría de las otras soluciones. Es limitado, ya que es bastante difícil redireccionar contenedores en hosts separados en un clúster dado, y los contenedores no se pueden reiniciar una vez conectados a la red, pero ofrece una forma rápida y relativamente fácil de contenedores de red en el mismo host. Es una buena manera de tener una idea de lo que el software que probablemente utilizará para resolver este problema lo está haciendo bajo el capó.

Además, es probable que también quiera consultar la network naciente de Docker, el consul de Hashicorp, Weaveworks progrium/consul , progrium/consul y gliderlabs/registrator Jeff Lindsay, y Google Kubernetes .

También están las ofertas de CoreOS que utilizan etcd , fleet y flannel .

Y si realmente quieres tener una fiesta, puedes girar un clúster para ejecutar Mesosphere , Deis o Flynn .

Si eres nuevo en la creación de redes (como yo), entonces deberías sacar tus lentes de lectura, pop "Paint The Sky With Stars - Lo mejor de Enya" en el Wi-Hi-Fi, y romper una cerveza - va a ser un tiempo antes de que realmente entiendas exactamente qué es lo que estás tratando de hacer. Sugerencia: está intentando implementar una Service Discovery Layer en su Cluster Control Plane . Es una forma muy agradable de pasar un sábado por la noche.

Es muy divertido, pero ojalá me hubiera tomado el tiempo para educarme mejor sobre la creación de redes en general antes de sumergirme en él. Finalmente encontré un par de posts de los benévolos dioses del Tutorial Ocean Digital: Introduction to Networking Terminology y Understanding ... Networking Introduction to Networking Terminology Understanding ... Networking . Sugiero leer esas algunas veces primero antes de bucear.

¡Que te diviertas!



Publicación original

Parece que no puedo entender el mapeo de puertos para los contenedores Docker . Específicamente, cómo pasar solicitudes de Nginx a otro contenedor, escuchando en otro puerto, en el mismo servidor.

Tengo un Dockerfile para un contenedor Nginx así:

FROM ubuntu:14.04
MAINTAINER Me <me@myapp.com>

RUN apt-get update && apt-get install -y htop git nginx

ADD sites-enabled/api.myapp.com /etc/nginx/sites-enabled/api.myapp.com
ADD sites-enabled/app.myapp.com /etc/nginx/sites-enabled/app.myapp.com
ADD nginx.conf /etc/nginx/nginx.conf

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

EXPOSE 80 443

CMD ["service", "nginx", "start"]



Y luego el archivo de configuración api.myapp.com ve así:

upstream api_upstream{

    server 0.0.0.0:3333;

}


server {

    listen 80;
    server_name api.myapp.com;
    return 301 https://api.myapp.com/$request_uri;

}


server {

    listen 443;
    server_name api.mypp.com;

    location / {

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_pass http://api_upstream;

    }

}

Y luego otro para app.myapp.com también.

Y luego corro:

sudo docker run -p 80:80 -p 443:443 -d --name Nginx myusername/nginx


Y todo se levanta bien, pero las solicitudes no se transfieren a los otros contenedores / puertos. Y cuando entro al contenedor de Nginx e inspecciono los registros, no veo errores.

¿Alguna ayuda?




Intenté usar el popular proxy inverso de Jason Wilder que funciona mágicamente para todos, y aprendí que no funciona para todos (es decir, para mí). Y soy nuevo en NGINX, y no me gustó que no entendiera las tecnologías que estaba tratando de usar.

Quería agregar mis 2 centavos, porque la discusión anterior acerca de linking contenedores juntos ahora está anticuada ya que es una característica obsoleta. Así que aquí hay una explicación sobre cómo hacerlo usando networks . Esta respuesta es un ejemplo completo de la configuración de nginx como un proxy inverso para un sitio web paginado estáticamente utilizando Docker Compose y la configuración de nginx.

TL; DR;

Agregue los servicios que necesitan para comunicarse entre sí en una red predefinida. Para una discusión paso a paso sobre las redes Docker, aprendí algunas cosas aquí: https://technologyconversations.com/2016/04/25/docker-networking-and-dns-the-good-the-bad-and- el feo/

Definir la red

En primer lugar, necesitamos una red en la que puedan hablar todos sus servicios de back-end. Llamé a mi web pero puede ser lo que quieras.

docker network create web

Crea la aplicación

Simplemente haremos una aplicación de sitio web simple. El sitio web es una página simple index.html servida por un contenedor nginx. El contenido es un volumen montado en el host en un content carpeta

DockerFile:

FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf

default.conf

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

docker-compose.yml

version: "2"

networks:
  mynetwork:
    external:
      name: web

services:
  nginx:
    container_name: sample-site
    build: .
    expose:
      - "80"
    volumes:
      - "./content/:/var/www/html/"
    networks:
      default: {}
      mynetwork:
        aliases:
          - sample-site

Tenga en cuenta que ya no necesitamos mapeo de puertos aquí. Simplemente exponemos el puerto 80. Esto es útil para evitar colisiones en los puertos.

Ejecute la aplicación

Encienda este sitio web con

docker-compose up -d

Algunos controles divertidos con respecto a las asignaciones de dns para su contenedor:

docker exec -it sample-site bash
ping sample-site

Este ping debería funcionar, dentro de su contenedor.

Construye el Proxy

Nginx Reverse Proxy:

Dockerfile

FROM nginx

RUN rm /etc/nginx/conf.d/*

Restablecemos todas las configuraciones del host virtual, ya que vamos a personalizarlo.

docker-compose.yml

version: "2"

networks:
  mynetwork:
    external:
      name: web


services:
  nginx:
    container_name: nginx-proxy
    build: .
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./conf.d/:/etc/nginx/conf.d/:ro
      - ./sites/:/var/www/
    networks:
      default: {}
      mynetwork:
        aliases:
          - nginx-proxy

Ejecute el Proxy

Arranca el proxy usando nuestra confianza

docker-compose up -d

Suponiendo que no hay problemas, entonces tiene dos contenedores en ejecución que pueden hablar entre ellos usando sus nombres. Vamos a probarlo.

docker exec -it nginx-proxy bash
ping sample-site
ping nginx-proxy

Configurar el host virtual

El último detalle es configurar el archivo de alojamiento virtual para que el proxy pueda dirigir el tráfico en función de cómo quiera configurar su coincidencia:

sample-site.conf para nuestra configuración de alojamiento virtual:

  server {
    listen 80;
    listen [::]:80;

    server_name my.domain.com;

    location / {
      proxy_pass http://sample-site;
    }

  }

En función de cómo se configuró el proxy, necesitará este archivo almacenado en su carpeta conf.d local que montamos a través de la declaración de volumes en el archivo docker-compose .

Por último, dile a nginx que vuelva a cargar su configuración.

docker exec nginx-proxy service nginx reload

Esta secuencia de pasos es la culminación de horas de fuertes dolores de cabeza mientras luché con el siempre doloroso error 502 Bad Gateway, y aprendí nginx por primera vez, ya que la mayor parte de mi experiencia fue con Apache.

Esta respuesta es para demostrar cómo matar el error 502 Bad Gateway que resulta de que los contenedores no pueden comunicarse entre sí.

Espero que esta respuesta salve a alguien por horas de dolor, ya que conseguir contenedores para hablar entre sí era realmente difícil de entender por alguna razón, a pesar de que era lo que esperaba que fuera un caso de uso obvio. Pero, de nuevo, soy tonto. Y, por favor, hágame saber cómo puedo mejorar este enfoque.