domingo, 11 de febrero de 2018

Resolver por nombre de dominio en docker

Recientemente he adquirido cierta práctica dockerizando mis trabajos, encuentro que es una manera muy cómoda de trabajar, independizando cada proyecto de los otros.  Como no podía ser de otra manera he intentado dar el siguiente paso y poner esto de docker en práctica no solo para desarrollo sino para staging o incluso producción.

Mientras que en mi ordenador local no me molesta tener que acceder al proyecto con localhost:80xx no creo que los visitantes encontraran esto muy práctico, amén de las penalizaciones que seguro que los motores de búsqueda (si acaso encontraran esas webs) podrían hacer.

Así que, este fin de semana me planteé como reto intentar poner un contenedor maestro que tuviera una copia de nginx y que resolviera, por nombre de dominio, dirigiendo el tráfico al contenedor adecuado.

Esto no es a priori una tarea trivial, al menos no trabajando con docker-compose. Por lo que me dispuse a hacer diferentes pruebas siguiendo este artículo https://www.thepolyglotdeveloper.com/2017/03/nginx-reverse-proxy-containerized-docker-applications/.

El truco, si se le puede llamar así, consiste en tener claro qué recursos son compartidos, en este caso los nombres de los contenedores, los puertos que exponen cada uno y como no, las redes que internamente crea docker para cada grupo de contenedores (dentro del mismo docker-compose.yml).

He creado un repositorio totalmente funcional OTB. https://github.com/jlaso/docker-nginx-reverseproxy-domain-name

Para explicar un poco el funcionamiento, decir que la madre del cordero se haya en como redirige el tráfico nginx. Veamos este archivo de configuración:

upstream prj-one {
    server prj_one:80;
}

server {
    listen 80;
    server_name one.web.dev;

    location / {
        proxy_pass         http://prj-one;
        proxy_redirect     off;
        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-Host $server_name;
    }
}


Lo primero que hacemos es crear un upstream al que le damos un nombre (arbitrario, pero con sentido)  que luego usaremos en el proxy_pass (más abajo).  Importante que el nombre del server de ese upstream sea exactamente el mismo que definamos en hostname en ese contenedor.

Por si aún no lo has visto, el puerto es 80 tanto en el listen (justo queremos que sean puertos estándar), pero también lo es en la cláusula server, porque la comunicación con ese container a nivel interno será por el puerto 80 (el puerto que exponemos en el Dockerfile).

No sé si se requieren más explicaciones más allá de que lo pruebes y comentes.

No hay comentarios:

Publicar un comentario