Docker: Gestionar dominios personalizados con Traefik

Esta documentación forma parte de la guía Enrutamiento HTTPS. Consulte la guía completa aquí: Cómo gestionar el enrutamiento HTTP y el cifrado TLS (HTTPS) en tus contenedores Docker.

👋 ¡Bienvenido a la documentación de Stackhero!

Stackhero ofrece una solución Docker cloud CaaS (Containers as a Service) lista para usar que proporciona una serie de beneficios, incluyendo:

  • Despliega fácilmente tus contenedores en producción con solo un docker-compose up.
  • Nombre de dominio personalizable asegurado con HTTPS (por ejemplo, https://api.tu-empresa.com, https://www.tu-empresa.com, https://backoffice.tu-empresa.com).
  • Rendimiento óptimo y seguridad robusta gracias a una VM privada y dedicada.
  • Actualizaciones sin esfuerzo con solo un clic.

Ahorra tiempo y simplifica tu vida: ¡solo toma 5 minutos probar la solución de alojamiento en la nube Docker CaaS de Stackhero y desplegar tus contenedores en producción!

En el ejemplo anterior, utilizamos el dominio predeterminado <XXXXXX>.stackhero-network.com. En la práctica, probablemente usarás tus propios dominios de empresa o proyecto, como www.my-company.com o api.my-project.io. La sección a continuación explica cómo configurar dominios personalizados.

En este ejemplo, configurarás el dominio api.my-project.io. Reemplaza my-project.io con un dominio que poseas y api con tu subdominio deseado.

Primero, actualiza la configuración DNS de tu dominio para que api.my-project.io apunte a tu dominio <XXXXXX>.stackhero-network.com.

  1. Inicia sesión en tu proveedor de dominio y accede a tu configuración DNS.
  2. Crea una nueva entrada llamada api (u otro subdominio de tu elección), establece su tipo en CNAME y establece su destino en <XXXXXX>.stackhero-network.com.

Ejemplo de configuración DNS en la interfaz DNS de CloudflareEjemplo de configuración DNS en la interfaz DNS de Cloudflare

Una vez configurado el DNS, puedes validarlo ejecutando:

host api.my-project.io

Deberías ver una respuesta similar a:

api.my-project.io is an alias for <XXXXXX>.stackhero-network.com

La propagación DNS puede tardar hasta 24 horas dependiendo de tu proveedor. Si el comando host no devuelve la respuesta esperada, espera y vuelve a intentarlo más tarde.

A continuación, actualiza tu archivo docker-compose.yml con la siguiente configuración:

services:
  api:
    image: traefik/whoami
    hostname: api
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`api.my-project.io`)" # Añade tu dominio aquí
      - "traefik.http.services.api.loadbalancer.server.port=<PORT>" # Reemplaza "<PORT>" con el puerto en el que tu API está escuchando
      - "traefik.http.routers.api.tls.certresolver=letsencrypt"

No olvides reemplazar api.my-project.io con tu dominio real en la etiqueta Traefik Host.

Despliega tu contenedor con:

docker-compose up -d

Luego visita https://api.my-project.io. Deberías ver una página de texto que muestra el nombre de host de tu contenedor api.

Prueba de que Traefik está gestionando nuestro tráfico HTTP con cifrado TLS para nuestro nuevo dominioPrueba de que Traefik está gestionando nuestro tráfico HTTP con cifrado TLS para nuestro nuevo dominio

En la primera creación del contenedor, los certificados TLS pueden tardar unos segundos en generarse. Si encuentras un error TLS, espera unos segundos y actualiza la página para permitir que se generen los certificados.

¡Felicidades, ahora has configurado tu primer dominio personalizado!

Al definir una URL de sitio web como my-company.com, es una buena idea configurar también un subdominio "www". Esto asegura que los usuarios que se conecten a través de www.my-company.com sean redirigidos a tu sitio principal y ayuda a evitar problemas de contenido duplicado.

En el ejemplo a continuación, se gestionan tanto my-company.com como www.my-company.com. Los usuarios que acceden a www.my-company.com son redirigidos a my-company.com:

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Añade ambos dominios aquí
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Reemplaza "<PORT>" con el puerto en el que tu frontend está escuchando
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Redirigir 'www.my-company.com' a 'my-company.com':
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Supongamos que tienes un contenedor dedicado a tu sitio de documentación. Podrías querer enrutar https://my-company.com/docs a este contenedor mientras envías otras solicitudes, como https://my-company.com/, a tu contenedor frontend. El ejemplo a continuación muestra cómo se logra esto:

services:
  documentations:
    image: traefik/whoami
    hostname: documentations
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.documentations.rule=Host(`my-company.com`) && PathPrefix(`/docs`)" # Define el prefijo de camino aquí
      - "traefik.http.services.documentations.loadbalancer.server.port=<PORT>" # Reemplaza "<PORT>" con el puerto en el que tu contenedor de documentación está escuchando
      - "traefik.http.routers.documentations.tls.certresolver=letsencrypt"

  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)"
      - "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Reemplaza "<PORT>" con el puerto en el que tu frontend está escuchando
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Redirigir 'www.my-company.com' a 'my-company.com':
      - 'traefik.http.routers.frontend.middlewares=redirect-www'
      - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
      - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
      - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"

Ahora, al visitar https://my-company.com/docs (o cualquier subruta como https://my-company.com/docs/something) se mostrará contenido del contenedor documentations. Otros caminos, por ejemplo https://my-company.com/help, serán servidos por el contenedor frontend.

Por defecto, Traefik se conecta al primer puerto expuesto del contenedor. En algunos casos, podrías necesitar especificar un puerto particular. El ejemplo a continuación demuestra cómo definir un puerto personalizado:

services:
  frontend:
    image: traefik/whoami
    hostname: frontend
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`my-company.com`)"
      - "traefik.http.routers.frontend.tls.certresolver=letsencrypt"

      # Enrutar tráfico de 'https://my-company.com' al contenedor 'frontend' en el puerto 80
      - "traefik.http.services.frontend.loadbalancer.server.port=80"