[nginx] Asignación de vhosts a los puertos Docker


Answers

Aquí hay dos respuestas posibles: (1) configurar puertos directamente con Docker y usar Nginx / Apache para proxy de los vhosts, o (2) usar Dokku para administrar puertos y fantasmas para usted (que es la forma en que aprendí a hacer el Método 1).

Método 1a (asignar puertos directamente con la ventana acoplable)

Paso 1: Configure nginx.conf o Apache en el host, con las asignaciones de números de puerto deseados. Este servidor web, que se ejecuta en el host, realizará el proxy vhost. No hay nada de especial en esto con respecto a Docker: es el host vhost normal. La parte especial viene a continuación, en el paso 2, para hacer que Docker use el número de puerto de host correcto.

Paso 2: Forzar asignaciones de números de puerto en Docker con "-p" para establecer las asignaciones de puertos Docker, y "-e" para establecer variables de entorno personalizadas en Docker, de la siguiente manera:

port=12345 # <-- the vhost port setting used in nginx/apache
IMAGE=myapps/container-1
id=$(docker run -d -p :$port -e PORT=$port $IMAGE)
# -p :$port will establish a mapping of 12345->12345 from outside docker to
# inside of docker.
# Then, the application must observe the PORT environment variable
# to launch itself on that port; This is set by -e PORT=$port.

# Additional goodies:
echo $id # <-- the running id of your container
echo $id > /app/files/CONTAINER # <-- remember Docker id for this instance
docker ps # <-- check that the app is running
docker logs $id # <-- look at the output of the running instance
docker kill $id # <-- to kill the app

Método 1b Puerto de aplicación codificado

... si su aplicación utiliza un puerto codificado, por ejemplo, el puerto 5000 (es decir, no se puede configurar a través de la variable de entorno PORT, como en el Método 1a), entonces se puede codificar a través de Docker de esta manera:

publicPort=12345
id=$(docker run -d -p $publicPort:5000 $IMAGE)
# -p $publicPort:5000 will map port 12345 outside of Docker to port 5000 inside
# of Docker. Therefore, nginx/apache must be configured to vhost proxy to 12345,
# and the application within Docker must be listening on 5000.

Método 2 (deja que Dokku descubra los puertos)

Por el momento, una buena opción para manejar los fantasmas de Docker es Dokku . Una opción próxima puede ser usar Flynn , pero a partir de ahora Flynn recién está comenzando y no está del todo listo. Por lo tanto, vamos con Dokku por ahora: después de seguir las instrucciones de instalación de Dokku, para un único dominio, habilite los fantasmas creando el archivo "VHOST":

echo yourdomain.com > /home/git/VHOST
# in your case: echo foo > /home/git/VHOST

Ahora, cuando una aplicación se envía a través de SSH a Dokku (consulte los documentos de Dokku para saber cómo hacerlo), Dokku mirará el archivo VHOST y, para la aplicación en particular presionada (digamos que presionó "contenedor-1"), generará el siguiente archivo:

/home/git/container-1/nginx.conf

Y tendrá los siguientes contenidos:

upstream container-1 { server 127.0.0.1:49162; }
server {
  listen      80;
  server_name container-1.yourdomain.com;
  location    / {
    proxy_pass  http://container-1;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

Cuando se reinicia el servidor, Dokku se asegurará de que Docker inicie la aplicación con el puerto asignado a su puerto inicialmente desplegado (49162 aquí), en lugar de asignarle aleatoriamente otro puerto. Para lograr esta asignación determinista, Dokku guarda el puerto asignado inicialmente en /home/git/container-1/PORT y en el siguiente lanzamiento establece el entorno PORT a este valor, y también asigna las asignaciones de puertos de Docker para que sea este puerto tanto en el del lado del host y de la aplicación. Esto se opone al primer lanzamiento, cuando Dokku establecerá PORT=5000 y luego calculará el puerto aleatorio que Dokku asigna en el lado VPS a 5000 en el lado de la aplicación. Es todo (e incluso podría cambiar en el futuro), ¡pero funciona!

La forma en que VHOST funciona, bajo el capó, es: al hacer un git push de la aplicación a través de SSH, Dokku ejecutará ganchos que viven en /var/lib/dokku/plugins/nginx-vhosts . Estos enlaces también se encuentran en el código fuente de Dokku y son responsables de escribir los archivos nginx.conf con la configuración de nginx.conf correcta. Si no tiene este directorio en /var/lib/dokku , intente ejecutar dokku plugins-install .

Question

Tengo un DNS comodín configurado para que todas las solicitudes web a un dominio personalizado (* .foo) se asignen a la dirección IP del host Docker. Si tengo varios contenedores ejecutando instancias de Apache (o Nginx), cada contenedor mapea el puerto de Apache (80) a algún puerto de entrada externo.

Lo que me gustaría hacer es realizar una solicitud al contenedor-1.foo, que ya está asignado a la dirección IP correcta (del host Docker) a través de mi servidor DNS personalizado, pero proxy la solicitud predeterminada del puerto 80 al Docker externo correcto. puerto de modo que la instancia correcta de Apache del contenedor especificado pueda responder en función del dominio personalizado. Del mismo modo, container-2.foo sería proxy para un segundo contenedor de Apache, y así sucesivamente.

¿Existe una solución preconstruida para esto ?, es mi mejor opción para ejecutar un proxy Nginx en el host Docker, o debería escribir un proxy node.js con el potencial de gestionar los contenedores Docker (iniciar / detener / reubicar a través de la web ), o ...? ¿Qué opciones tengo para hacer que el uso de los contenedores Docker sea más parecido a un evento natural y no a algo con puertos extraños y malabares de contenedores?




Links