Todas las guías de despliegue Despliegue

Certificados SSL con Docker y proxies inversos

Los contenedores Docker normalmente no gestionan SSL por sí mismos; un proxy inverso al frente termina TLS y reenvía el tráfico descifrado al contenedor. Esta guía cubre los tres enfoques más comunes.

Enfoque 1: Proxy inverso Nginx con certificado manual

El enfoque más sencillo para despliegues pequeños. Obtén un certificado desde GetHTTPS y móntalo en un contenedor Nginx.

docker-compose.yml

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs/fullchain.pem:/etc/ssl/fullchain.pem:ro
      - ./certs/privkey.pem:/etc/ssl/privkey.pem:ro
    depends_on:
      - app

  app:
    image: your-app:latest
    expose:
      - "3000"

nginx.conf

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate     /etc/ssl/fullchain.pem;
    ssl_certificate_key /etc/ssl/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://app:3000;
        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-Proto $scheme;
    }
}

server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;
}

Para renovar: Reemplaza los archivos en ./certs/ con los nuevos de GetHTTPS y ejecuta docker compose exec nginx nginx -s reload.

Enfoque 2: Traefik con Let’s Encrypt automático

Traefik es un proxy inverso diseñado para contenedores. Puede obtener y renovar certificados de Let’s Encrypt automáticamente.

docker-compose.yml

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/acme/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik-acme:/acme

  app:
    image: your-app:latest
    labels:
      - "traefik.http.routers.app.rule=Host(`yourdomain.com`)"
      - "traefik.http.routers.app.tls.certresolver=letsencrypt"
      - "traefik.http.services.app.loadbalancer.server.port=3000"

volumes:
  traefik-acme:

Traefik se encarga de todo: emisión del certificado, renovación y terminación HTTPS. No se necesita gestión manual de certificados.

Enfoque 3: Caddy (HTTPS sin configuración)

Caddy obtiene y renueva certificados de Let’s Encrypt automáticamente sin necesidad de configuración.

docker-compose.yml

services:
  caddy:
    image: caddy:2
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
    depends_on:
      - app

  app:
    image: your-app:latest
    expose:
      - "3000"

volumes:
  caddy-data:

Caddyfile

yourdomain.com {
    reverse_proxy app:3000
}

Esa es toda la configuración. Caddy obtiene un certificado de Let’s Encrypt y lo renueva automáticamente.

¿Qué enfoque elegir?

Nginx + certificado manualTraefikCaddy
ConfiguraciónMedia (config + archivos de cert)Media (labels)Mínima
Renovación automáticaNo (manual)
FlexibilidadAltaAltaMedia
Curva de aprendizajeBaja (familiar)MediaBaja
Mejor paraDespliegues pequeños, control totalContenedores dinámicos, microserviciosSitios simples, configuración mínima

Renovar certificados en Docker

Enfoque 1 (Nginx + manual):

# Replace cert files in your local ./certs/ directory
cp new-fullchain.pem ./certs/fullchain.pem
cp new-privkey.pem ./certs/privkey.pem

# Reload Nginx inside the container (no restart needed)
docker compose exec nginx nginx -s reload

Enfoque 2 (Traefik) y 3 (Caddy):

Automático: gestionan la renovación internamente. Los certificados se almacenan en volúmenes Docker (traefik-acme o caddy-data) y persisten entre reinicios del contenedor.

Docker Swarm: uso de secrets

Para despliegues con Docker Swarm, usa Docker secrets en lugar de montar archivos de certificado directamente:

# Create secrets from your cert files
docker secret create ssl_cert fullchain.pem
docker secret create ssl_key privkey.pem
# In docker-compose.yml (deploy mode)
services:
  nginx:
    image: nginx:alpine
    secrets:
      - ssl_cert
      - ssl_key
    configs:
      - source: nginx_conf
        target: /etc/nginx/conf.d/default.conf

secrets:
  ssl_cert:
    external: true
  ssl_key:
    external: true

Los secrets se montan en /run/secrets/ssl_cert y /run/secrets/ssl_key dentro del contenedor, cifrados en reposo y en tránsito.

Errores comunes

Incluir certificados dentro de las imágenes Docker

# ❌ NEVER do this
COPY fullchain.pem /etc/ssl/fullchain.pem
COPY privkey.pem /etc/ssl/privkey.pem

Los certificados expiran cada 90 días. Incluirlos en la imagen significa reconstruir y redesplegar cada 60 días. Monta siempre los certificados como volúmenes o secrets.

Olvidar exponer el puerto 80

El puerto 80 es necesario para:

  • Redirección HTTP → HTTPS
  • Desafío HTTP-01 de Let’s Encrypt (para la renovación automática de Traefik/Caddy)
ports:
  - "80:80"    # Don't forget this
  - "443:443"

No persistir los datos ACME

Traefik y Caddy almacenan sus certificados de Let’s Encrypt y claves de cuenta en volúmenes. Sin persistencia, solicitan nuevos certificados en cada reinicio del contenedor y alcanzarán los límites de tasa:

volumes:
  traefik-acme:    # MUST be a named volume, not anonymous
  caddy-data:

Preguntas frecuentes

¿Puede mi contenedor de aplicación manejar SSL directamente?

Es posible, pero no se recomienda. El patrón de proxy inverso (terminar TLS en el borde, reenviar HTTP plano internamente) es estándar porque: la aplicación no necesita saber sobre certificados, la renovación no requiere reiniciar la aplicación y se centraliza la configuración TLS.

¿Cómo manejo SSL para múltiples contenedores?

Con Traefik o Caddy, añade labels/configuración para cada servicio; obtendrán certificados separados automáticamente. Con Nginx, añade múltiples bloques server en la configuración.

¿Debo usar GetHTTPS o el ACME integrado de Traefik?

Usa el ACME integrado de Traefik/Caddy para producción, ya que gestiona la renovación automáticamente. Usa GetHTTPS cuando necesites un certificado para el enfoque de proxy inverso Nginx (Enfoque 1) o para entornos donde el contenedor no tiene acceso directo a internet para los desafíos ACME.

¿Cómo monto certificados de forma segura en Docker?

Monta como solo lectura (:ro), usa Docker secrets para la clave privada en modo Swarm y asegúrate de que solo el contenedor del proxy inverso tenga acceso a los archivos del certificado. Nunca incluyas certificados dentro de una imagen Docker, ya que expirarán y tendrías que reconstruir.

¿Puedo usar certificados de GetHTTPS con Kubernetes?

Sí. Crea un secret TLS de Kubernetes a partir de los archivos de certificado de GetHTTPS:

kubectl create secret tls my-tls-cert --cert=fullchain.pem --key=privkey.pem

Luego referéncialo en tu recurso Ingress. Para renovación automatizada en Kubernetes, considera cert-manager con un ClusterIssuer de Let’s Encrypt.

Artículos relacionados

Despliegue 2026-05-08
Cómo instalar un certificado SSL en Nginx
Guía paso a paso para instalar un certificado SSL en Nginx. Cubre subida de archivos, configuración completa del bloque server, mejores prácticas TLS, HTTP/2, HSTS, redirección y solución de 6 errores comunes.
Primeros pasos 2026-05-08
Cómo obtener un certificado SSL gratuito (guía paso a paso)
Obtén un certificado SSL gratuito de Let's Encrypt en 5 minutos — sin software que instalar, sin cuenta que crear. Guía completa con 4 métodos, ambos tipos de desafío, instalación en 6 plataformas y solución de problemas.
Comparar 2026-05-07
Clientes ACME en navegador vs línea de comandos
Compara clientes ACME basados en navegador (como GetHTTPS) con herramientas CLI (Certbot, acme.sh). Comprende las diferencias en privacidad, automatización y casos de uso.
Obtén un certificado SSL gratuito en tu navegador
Sin instalación, sin cuenta. Tu clave privada nunca sale de tu dispositivo.
Obtener certificado