8
Traefik
groales edited this page 2025-12-03 14:24:58 +01:00

Despliegue con Traefik

Esta guía explica cómo desplegar Vaultwarden usando Traefik como reverse proxy.

Ventajas de usar Traefik

  • 🔒 Certificados SSL automáticos con Let's Encrypt
  • 🔄 Renovación automática de certificados
  • 🌐 Redirección HTTP → HTTPS integrada
  • 🔌 WebSocket preconfigurado para sincronización en tiempo real
  • 📝 Configuración declarativa mediante labels de Docker

📋 Requisitos Previos

Antes de comenzar, asegúrate de tener:

  • Traefik funcionando con soporte para Let's Encrypt
  • Red Docker proxy creada y Traefik conectado a ella
  • Dominio configurado apuntando a tu servidor
  • Puertos 80 y 443 abiertos en el firewall
  • ADMIN_TOKEN generado

Verificar Red Proxy

docker network ls | grep proxy

Si no existe, créala:

docker network create proxy

🔑 Generar ADMIN_TOKEN

Antes de cualquier despliegue, genera un token en formato Argon2 seguro:

# 1. Generar token aleatorio
openssl rand -base64 48

# 2. Convertir a formato Argon2 seguro
docker run --rm -it vaultwarden/server:latest /vaultwarden hash
# Pega el token cuando lo solicite

Guarda el hash Argon2 resultante (empieza con $argon2id$), lo necesitarás para las variables de entorno.

⚠️ Importante: Usa comillas simples en el archivo .env para evitar que $ se interprete como variable.


🚀 Despliegue desde Portainer

Opción A: Git Repository (Recomendada)

Esta opción mantiene tu stack actualizado con el repositorio Git.

  1. En Portainer, ve a StacksAdd stack

  2. Nombre del stack: vaultwarden

  3. Selecciona Git Repository

  4. Configura el repositorio:

    • Repository URL: https://git.ictiberia.com/groales/vaultwarden
    • Repository reference: refs/heads/main
    • Compose path: docker-compose.yml
    • Additional paths: docker-compose.override.traefik.yml.example

    ⚠️ Nota: Si usas NPM en lugar de Traefik, no necesitas Additional paths.

  5. En Environment variables, añade:

DOMAIN_HOST=vaultwarden.tudominio.com
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$...'

⚠️ Importante:

  • DOMAIN_HOST es el dominio sin protocolo
  • Usa comillas simples en ADMIN_TOKEN para evitar que $ se interprete como variable
  • Reemplaza con tu hash Argon2 real generado anteriormente
  • Otras opciones se configuran desde el panel /admin
  1. Haz clic en Deploy the stack

Opción B: Web Editor

Si prefieres tener el compose completo en Portainer:

  1. En Portainer, ve a StacksAdd stack
  2. Nombre del stack: vaultwarden
  3. Selecciona Web editor
  4. Copia y pega este contenido:
services:
  vaultwarden:
    container_name: vaultwarden
    image: vaultwarden/server:latest
    restart: unless-stopped
    environment:
      ADMIN_TOKEN: ${ADMIN_TOKEN}
      TZ: Europe/Madrid
    volumes:
      - vaultwarden_data:/data
    networks:
      - proxy
    labels:
      # HTTP → HTTPS redirect
      - "traefik.enable=true"
      - "traefik.http.routers.vaultwarden-http.rule=Host(`${DOMAIN_HOST}`)"
      - "traefik.http.routers.vaultwarden-http.entrypoints=web"
      - "traefik.http.routers.vaultwarden-http.middlewares=redirect-to-https@docker"
      
      # HTTPS router for main service
      - "traefik.http.routers.vaultwarden.rule=Host(`${DOMAIN_HOST}`)"
      - "traefik.http.routers.vaultwarden.entrypoints=websecure"
      - "traefik.http.routers.vaultwarden.tls=true"
      - "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"
      - "traefik.http.routers.vaultwarden.service=vaultwarden-svc"
      - "traefik.http.services.vaultwarden-svc.loadbalancer.server.port=80"
      
      # WebSocket support for /notifications/hub
      - "traefik.http.routers.vaultwarden-ws.rule=Host(`${DOMAIN_HOST}`) && Path(`/notifications/hub`)"
      - "traefik.http.routers.vaultwarden-ws.entrypoints=websecure"
      - "traefik.http.routers.vaultwarden-ws.tls=true"
      - "traefik.http.routers.vaultwarden-ws.tls.certresolver=letsencrypt"
      - "traefik.http.routers.vaultwarden-ws.service=vaultwarden-ws-svc"
      - "traefik.http.services.vaultwarden-ws-svc.loadbalancer.server.port=3012"
      
      # Redirect middleware
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"

volumes:
  vaultwarden_data:
    name: vaultwarden_data

networks:
  proxy:
    external: true
  1. En Environment variables, añade las mismas variables que en la Opción A

  2. Haz clic en Deploy the stack

🖥️ Despliegue desde CLI

1. Clonar el repositorio

git clone https://git.ictiberia.com/groales/vaultwarden.git
cd vaultwarden

2. Copiar el archivo override

cp docker-compose.override.traefik.yml.example docker-compose.override.yml

3. Configurar variables de entorno

cp .env.example .env

Edita el archivo .env y configura:

DOMAIN_HOST=vaultwarden.tudominio.com
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$...'  # Entre comillas simples

4. Iniciar el servicio

docker compose up -d

5. Verificar el despliegue

# Ver logs
docker compose logs -f vaultwarden

# Verificar que el contenedor está corriendo
docker compose ps

🔧 Configuración de Traefik

Labels Explicados

El archivo override de Traefik incluye varios routers y servicios:

Router HTTP (Redirección)

- "traefik.http.routers.vaultwarden-http.rule=Host(`${DOMAIN_HOST}`)"
- "traefik.http.routers.vaultwarden-http.entrypoints=web"
- "traefik.http.routers.vaultwarden-http.middlewares=redirect-to-https@docker"

Captura tráfico HTTP y lo redirige a HTTPS.

Router HTTPS Principal

- "traefik.http.routers.vaultwarden.rule=Host(`${DOMAIN_HOST}`)"
- "traefik.http.routers.vaultwarden.entrypoints=websecure"
- "traefik.http.routers.vaultwarden.tls=true"
- "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"

Maneja tráfico HTTPS con certificado Let's Encrypt.

Router WebSocket

- "traefik.http.routers.vaultwarden-ws.rule=Host(`${DOMAIN_HOST}`) && Path(`/notifications/hub`)"
- "traefik.http.services.vaultwarden-ws-svc.loadbalancer.server.port=3012"

Ruta específica para WebSocket en el puerto 3012, necesario para sincronización en tiempo real.

Verificar Configuración en Traefik

Si tienes el dashboard de Traefik habilitado, verifica:

  1. Ve a http://tu-servidor:8080 (o el puerto de tu dashboard)
  2. En HTTP Routers, deberías ver:
    • vaultwarden-http (redirección)
    • vaultwarden (servicio principal)
    • vaultwarden-ws (WebSocket)
  3. En HTTP Services, verifica:
    • vaultwarden-svc@docker (puerto 80)
    • vaultwarden-ws-svc@docker (puerto 3012)

Verificación del Despliegue

1. Verificar Acceso Web

Abre tu navegador y ve a: https://vaultwarden.tudominio.com

Deberías ver la página de login/registro de Vaultwarden con certificado SSL válido.

2. Verificar WebSocket

Los WebSockets son esenciales para la sincronización en tiempo real. Verifica en los logs:

docker compose logs vaultwarden | grep -i websocket

Deberías ver:

[INFO] WebSocket server listening on 0.0.0.0:3012

3. Verificar Panel de Administración

Ve a: https://vaultwarden.tudominio.com/admin

Introduce tu ADMIN_TOKEN. Si puedes acceder, la configuración es correcta.

4. Prueba de Sincronización

  1. Crea una cuenta en Vaultwarden
  2. Añade una contraseña desde la web
  3. Instala la extensión de navegador Bitwarden
  4. Configura el servidor: https://vaultwarden.tudominio.com
  5. Inicia sesión
  6. Verifica que la contraseña aparece inmediatamente (WebSocket funcionando)

🔒 Seguridad Adicional

Restringir Acceso al Admin Panel

Puedes añadir autenticación básica de Traefik para el panel de administración:

labels:
  # Admin panel con autenticación extra
  - "traefik.http.routers.vaultwarden-admin.rule=Host(`${DOMAIN_HOST}`) && PathPrefix(`/admin`)"
  - "traefik.http.routers.vaultwarden-admin.middlewares=admin-auth"
  - "traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$hash$$generado"

Genera el hash:

htpasswd -nb admin tu_password

Headers de Seguridad

Considera añadir headers de seguridad adicionales:

labels:
  - "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
  - "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.security-headers.headers.stsPreload=true"
  - "traefik.http.routers.vaultwarden.middlewares=security-headers"

🔄 Actualización

Desde Portainer (Git Repository):

  1. Ve al stack vaultwarden
  2. Clic en Pull and redeploy

Desde CLI:

docker compose pull
docker compose up -d

📖 Siguientes Pasos

🆘 Solución de Problemas

Error de certificado SSL

Síntoma: Certificado inválido o autofirmado

Solución:

  1. Verifica que el dominio apunta a tu servidor
  2. Comprueba que Traefik tiene acceso a Let's Encrypt
  3. Revisa logs de Traefik: docker logs traefik
  4. Verifica el certresolver en la configuración de Traefik

WebSocket no funciona

Síntoma: Sincronización lenta, no en tiempo real

Solución:

  1. Verifica logs: docker compose logs vaultwarden | grep websocket
  2. Comprueba que el router WebSocket existe en Traefik
  3. Prueba manualmente: wscat -c wss://vaultwarden.tudominio.com/notifications/hub

No puedo acceder al servicio

Síntoma: Timeout o conexión rechazada

Solución:

  1. Verifica que el contenedor está corriendo: docker compose ps
  2. Comprueba que está en la red proxy: docker network inspect proxy
  3. Revisa logs de Traefik para errores de routing
  4. Verifica que los puertos 80/443 están abiertos

Última actualización: Diciembre 2025