Añadir HTTPS a contenedores de forma fácil
18 de septiembre de 2019Últimamente me pasa que desarrollo algo en NodeJS, hago un docker de esa aplicación (una API, una web, etc) y al lanzar el docker en el servidor final o de prueba me encuentro que ahora necesito hacer cosas extra para añadir la S al HTTP, pues he encontrado una forma para no preocuparme por esto.
¿Qué vamos a conseguir?
Añadir el HTTPS de forma automática a los docker sin añadir mucho más que 2 variables a cada contenedor que despleguemos, solo con eso nos podemos olvidar de todo, las herramientas se encargarán de proveer, crear y mantener los certificados a las aplicaciones que lancemos.
Listado de cosas que necesitamos
- Docker
- Un contenedor que asegurar
- Un nombre de dominio
- Un servidor para correr docker
- Contenedor nginx-proxy
- Contenedor nginx-proxy-letsencrypt-companion
(Opcional) Instalar portainer para agilizar todo
Últimamente soy muy fan de instalar portainer (gestor visual web de contenedores), voy a poner los comandos de consola pero dejo esta recomendación aquí por si acaso.
Lanzando nginx-proxy
Ahora queremos lanzar el contenedor de nginx de esta forma
docker run --detach \
--name nginx-proxy \
--publish 80:80 \
--publish 443:443 \
--volume /etc/nginx/certs \
--volume /etc/nginx/vhost.d \
--volume /usr/share/nginx/html \
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
jwilder/nginx-proxy
Lo que hace es añadir 3 volúmenes extra a nginx-proxy y lo lanza usando los puertos 80 y 443.
Lanzando letsencrypt-nginx-proxy-companion
Un comando, parecido al anterior
Poner nuestro mail en la variable de entorno hace que se nos notifique si algo ha fallado y van a caducar los certificados.
docker run --detach \
--name nginx-proxy-letsencrypt \
--volumes-from nginx-proxy \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
--env "DEFAULT_EMAIL=TU@MAIL.COM" \
jrcs/letsencrypt-nginx-proxy-companion
Añadir todas las aplicaciones que queremos
Ahora cuando lancemos una aplicación le tenemos que añadir 2 variables de entorno extras, que le dirán a nginx-proxy y al letsencrypt-companion que dominio o subdominio va a que contenedor.
Yo, por ejemplo he desarrollado una API y la lanzo en otro contenedor con un subdominio que he creado (en este caso en cloudflare) api.jaludev.com apuntando a la dirección IP del contenedor.
docker run --detach \
--name your-proxyed-app \
--env "VIRTUAL_HOST=api.jaludev.com" \
--env "LETSENCRYPT_HOST=api.jaludev.com" \
nginx
En unos minutos ya reconocerá la dirección y habrá generado los certificados, lo mejor de todo es que se renuevan automáticamente.