Hola gente hoy les voy a contar como usar Træfik y emitir certificados wildcard con Let’s Encrypt para nuestros dockers bajo el mismo dominio.

Requisitos:
1- Instancia publica en la nube o Instancia VMware/KVM con puerto 80 y 443 publicos (Yo voy a usar AWS )
2- Depende el proveedor de dns que vamos a usar ,pero vamos a necesitar credenciales y acceso a la zona de dns para crear registros(En mi caso voy a usar route53.)

3-Apps en docker-compose para testear funcionamiento.

Start:


Tenemos 2 opciones:
1 – crear nuestros registros A manualmente y apuntar a la instancia de Traefik.

2- Crear un registro A wildcard y apuntara todo a la instancia del Traefik.

Proceedemos a conectarnos a nuestra instancia.

Descargamos traefik y configuramos

wget https://github.com/containous/traefik/releases/download/v1.6.2/traefik_linux-amd64
mv traefik_linux-amd64 /usr/bin/traefik
chmod +x /usr/bin/traefik
cd /tmp
mkdir traefik_config
touch /traefik_config/acme.json
chmod 0600 /traefik_config/acme.json

Generamos nuestra de config de traefik.toml

Existen 2 opciones usar Træfik resolviendo containers a traves del socket de docker o por ip/localhost.

Configuracion para Wildcard traefik.toml requiere credenciales de tu zoneid en mi caso uso route53(que ya lo tengo configurado con boto3 desde awscli)

InsecureSkipVerify = true

defaultEntryPoints = ["http", "https"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

# Set up logging.
traefikLogsFile = "/tmp/traefik_config/traefik-stderr.log"
accessLogsFile = "/tmp/traefik_config/traefik-stdout.log"
logLevel = "DEBUG"

# Set the Web Admin Port.
[web]
address = ":8095"

# Configure Traefik to watch a file for config changes.
[docker]
  endpoint = "unix:///var/run/docker.sock"
  watch = true
  exposedbydefault = false
  usebindportip = true
  swarmmode = false

# Enable ACME (Let's Encrypt): automatic SSL
[acme]
# Email address used for registration
email = "[email protected]"
storageFile = "/tmp/traefik_config/acme.json"
acmeLogging = true
onDemand = false
OnHostRule = true
entryPoint = "https"
[acme.httpChallenge]
  entryPoint = "http"
[acme.dnsChallenge]
  provider = "route53"
  delayBeforeCheck = 0
[[acme.domains]]
   main = "*.itshellweb.org"
   sans = ["itshellweb.org"]

sin wildcard , especificando nombres de registros.

InsecureSkipVerify = true
defaultEntryPoints = ["http", "https"]
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
      entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

# Setup logging.
traefikLogsFile = "/tmp/traefik_config/traefik.log"
accessLogsFile = "/tmp/traefik_config/access.log"
logLevel = "DEBUG"

# Set the Web Admin Port.
[web]
address = ":8095"

# Configure Traefik to watch a file for config changes.
[docker]
  endpoint = "unix:///var/run/docker.sock"
  watch = true
  exposedbydefault = false
  usebindportip = true
  swarmmode = false

# Enable ACME (Let's Encrypt): automatic SSL
[acme]
# Email address used for registration
email = "[email protected]"
storageFile = "/tmp/traefik_config/acme.json"
acmeLogging = true
onDemand = false
OnHostRule = true
entryPoint = "https"
[acme.httpChallenge]
  entryPoint = "http"
[[acme.domains]]
   main = "itshellweb.org"
   sans = ["app1.itshellweb.org","app2.itshellweb.org","app3.itshellweb.org","app4.itshellweb.org"]

A continuacion vamos a instalar supervisor para iniciar a traefik como un demon.

yum install python-setuptools
easy_install supervisor
echo_supervisord_conf > /etc/supervisord.conf

Configuramos supervisor para iniciar Træfik tambien podemos pasar variables de entorno para que las levante supervisor.

[[email protected] tmp]# vi /etc/supervisord.conf

[unix_http_server]
file=/tmp/traefik_config/supervisor.sock
chmod=0777

[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=false               ; start in foreground if true; default false
minfds=1024                  ; min. avail startup file descriptors; default 1024
minprocs=200                 ; min. avail process descriptors;default 200

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/traefik_config/supervisor.sock ; use a unix:// URL  for a unix socket

[program:traefik]
command=/usr/bin/traefik --configFile=/tmp/traefik_config/traefik.toml
autostart=true
autorestart=true
stderr_logfile=/tmp/traefik_config/traefik-stderr.log
stderr_logfile_maxbytes=1MB
stderr_logfile_backups=10
stdout_logfile=/tmp/traefik_config/traefik-stdout.log
stdout_logfile_maxbytes=1MB
stdout_logfile_backups=10
user=root
environment=variable="AKIAJFPW123"

Con traefik ya configurado y supervisor vamos a proceder a levantar los docker-compose de nuestras aplicaciones.

Un ejemplo de 4 aplicaciones con docker compose.

[[email protected] ec2-user]# cat app1/docker-compose.yml

version: '3'

services:
  app1:
      hostname: app1
      image: app1:1.0
      labels:
        traefik.backend: 'app-1'
        traefik.frontend.rule: 'Host: app1.itshellweb.org'
        traefik.enable: 'true'
        traefik.port: '80'

networks:
  nginx_default:

[[email protected] ec2-user]# cat app2/docker-compose.yml

version: '3'

services:
  app2:
      hostname: app2
      image: app2:1.0
      labels:  
        traefik.backend: 'app-2'
        traefik.frontend.rule: 'Host: app2.itshellweb.org'
        traefik.enable: 'true'
        traefik.port: '80'

networks:
  nginx_default:

[[email protected] ec2-user]# cat app3/docker-compose.yml

version: '3'

services:
  app3:
      hostname: app3
      image: app3:1.0
      labels:  
        traefik.backend: 'app-3'
        traefik.frontend.rule: 'Host: app3.itshellweb.org'
        traefik.enable: 'true'
        traefik.port: '80'

networks:
  nginx_default:

[[email protected] ec2-user]# cat app4/docker-compose.yml

version: '3'

services:
  app4:
      hostname: app4
      image: app4:1.0
      labels:  
        traefik.backend: 'app-4'
        traefik.frontend.rule: 'Host: app4.itshellweb.org'
        traefik.enable: 'true'
        traefik.port: '80'

networks:
  nginx_default:

Ahora vamos a levantar nuestros 4 dockers compose.

docker-compose -f app1/docker-compose.yml up -d
docker-compose -f app2/docker-compose.yml up -d
docker-compose -f app3/docker-compose.yml up -d
docker-compose -f app4/docker-compose.yml up -d

Yo estoy ejecutando docker en un nodo que esta siendo utilizado por swarm por eso me aparecen los Warning.

# docker ps

Si todo salio bien ahora vamos a ejecutar traefik ingresamos en /tmp/traefik_config/ y ejecutados traefik -c traefik.toml

traefik -c traefik.toml

Si nuestra configuracion es correcta vamos a ver algo asi, en este caso ya estamos preparados para ejecutar supervisor y revisar que todo funcione.

Levanto supervisor y reviso que traefik corra en los puertos configurados.

Dashboard de Traeffik

Nota: Si nosotros levantamos un nuevo APP ejemplo5 y ejecutamos el compose automaticamente el sitio app5 deberia tener nuestro certificado wildcard.

Espero que les sea de ayuda saludos!