Alojar multiples webs con Docker en VPS con SSL

Hoy voy a explicar como alojar en un mismo VPS varios proyectos web usando Docker y con certificado SSL para todos. De esta forma, con un VPS mas o menos potente podemos alojar muchas webs sin tener que pagar para cada proyecto un VPS con lo que ahorraremos dinero en ese sentido.

Para ello he seguido esta guia https://blog.ssdnodes.com/blog/host-multiple-ssl-websites-docker-nginx/ la cual me ha sido muy util y sencilla. Le doy las gracias desde aquí.

Para empezar todos los proyectos deben usar docker. En ese caso si tenemos alguno corriendo sobre nuestro VPS deberemos pararlo durante unos minutos hasta que acabemos de configurarlo todo.

Os explico paso a paso:

1- Desde el home del VPS, creamos un directorio para usar una imagen de docker que hará de proxy inverso de todos nuestros sitios web:

$ mkdir nginx-proxy && cd nginx-proxy

2- Creamos una network de docker para meter todos los contenedores en la misma red:

$ docker network create nginx-proxy

3- Dentro de la carpeta nginx-proxy creamos un archivo y pegamos la siguiente configuración:

$ nano docker-compose.yml
version: '3'

services:
  nginx:
    image: nginx:1.13.1
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"

  dockergen:
    image: jwilder/docker-gen:0.7.3
    container_name: nginx-proxy-gen
    depends_on:
      - nginx
    command: -notify-sighup nginx-proxy -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro

  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-proxy-le
    depends_on:
      - nginx
      - dockergen
    environment:
      NGINX_PROXY_CONTAINER: nginx-proxy
      NGINX_DOCKER_GEN_CONTAINER: nginx-proxy-gen
    volumes:
      - conf:/etc/nginx/conf.d
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html
      - certs:/etc/nginx/certs
      - /var/run/docker.sock:/var/run/docker.sock:ro

volumes:
  conf:
  vhost:
  html:
  certs:

# Do not forget to 'docker network create nginx-proxy' before launch, and to add '--network nginx-proxy' to proxied containers. 

networks:
  default:
    external:
      name: nginx-proxy

4- Despues guardamos los cambios y ejecutamos el siguiente comando en la misma carpeta, el cual nos descarga una configuración para que funcione el SSL:

$ curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > nginx.tmpl

5- Arrancamos el contenedor de nginx-proxy:

$ docker-compose up -d

Deberiamos ver 3 contendores corriendo con este nombre:

CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS                                      NAMES
9ea5fffc24dd        jrcs/letsencrypt-nginx-proxy-companion   "/bin/bash /app/en..."   4 minutes ago       Up 4 minutes                                                   nginx-proxy-le
e2288dfc3c5c        jwilder/docker-gen:0.7.3                 "/usr/local/bin/do..."   4 minutes ago       Up 3 seconds                                                   nginx-proxy-gen
eda8f12bd829        nginx:1.13.1                             "nginx -g 'daemon ..."   4 minutes ago       Up 4 minutes        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   nginx-proxy

6- Ahora debemos configurar nuestros DNS de cada sitio web. Para ello, desde el panel de tu proveedor de dominios, accede a cada uno y crea/modifica un registro de tipo A apuntando a la IP de tu VPS o servidor.

7- Para cada proyecto debemos añadir 3 variables de entorno y agregarlos a la network que hemos creado inicialmente:

environment:
    VIRTUAL_HOST: www.example.com, example.com
    LETSENCRYPT_HOST: www.example.com, example.com
    LETSENCRYPT_EMAIL: foo@example.com
networks:
  default:
    external:
      name: nginx-proxy
expose:
  - 8091:80 # O el puerto que estes usando para ese proyecto en el contenedor apuntando al 80 de dentro de docker

Ejemplo de como podria ser el docker-compose.yml de uno de nuestros proyectos(atencion a la negrita):

version: '3'

services:
  example-app:
    image: example/example-app
    expose:
      - 80
    environment:
      VIRTUAL_HOST: app.example.com
      LETSENCRYPT_HOST: app.example.com
      LETSENCRYPT_EMAIL: foo@example.com

networks:
    default:
        external:
            name: nginx-proxy

8- Una vez se hayan propagado las DNS de los proyectos(Puede tardar hasta varias horas), cuando accedamos a los dominios configurados, ya deberia cargarnos la version HTTPS con nuestro certificado SSL firmado y seguro.

Espero que os sea útil y sencillo. En mi caso he estado peleandome con algunos problemas que tuve, pero al final lo consegui.

Si os ha gustado esta entrada, no dudeis en compartirla con vuestros colegas y foros.

Un saludo ¡

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.