4
Traefik
groales edited this page 2025-12-04 16:52:46 +01:00

Despliegue con Traefik

Guía para desplegar BookStack con Traefik como proxy inverso.

Requisitos

  • Stack de Traefik desplegado y funcionando
  • Red Docker proxy creada
  • DNS apuntando al servidor
  • Contraseña de BD generada

Despliegue desde Portainer

1. Configurar Variables

En Portainer, al crear el stack con Git Repository, configura:

Environment variables:

# Claves requeridas
APP_KEY=base64:tu_clave_generada
DB_PASSWORD=tu_password_generado

# Base de datos (valores por defecto)
DB_NAME=bookstack
DB_USER=bookstack

# Dominio (requerido para APP_URL)
DOMAIN_HOST=bookstack.tudominio.com

2. Subir Archivo Override

En Portainer, en la sección Additional paths:

  • Añade: docker-compose.override.traefik.yml.example

O si usas Web editor, añade las labels manualmente al servicio bookstack.

3. Desplegar

Click en Deploy the stack y espera 1-2 minutos.

4. Verificar

  • Accede a https://bookstack.tudominio.com
  • Verifica certificado SSL (candado verde)
  • Login con admin@admin.com / password
  • Cambia la contraseña inmediatamente

Labels de Traefik

El archivo docker-compose.override.traefik.yml.example contiene:

services:
  bookstack:
    labels:
      # Habilitar Traefik
      - traefik.enable=true
      
      # Router HTTP (redirige a HTTPS)
      - traefik.http.routers.bookstack-http.rule=Host(`${DOMAIN_HOST}`)
      - traefik.http.routers.bookstack-http.entrypoints=web
      - traefik.http.routers.bookstack-http.middlewares=redirect-to-https
      
      # Router HTTPS
      - traefik.http.routers.bookstack.rule=Host(`${DOMAIN_HOST}`)
      - traefik.http.routers.bookstack.entrypoints=websecure
      - traefik.http.routers.bookstack.tls=true
      - traefik.http.routers.bookstack.tls.certresolver=letsencrypt
      - traefik.http.routers.bookstack.service=bookstack-svc
      - traefik.http.services.bookstack-svc.loadbalancer.server.port=80
      
      # Redirect middleware
      - traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
      - traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true

Explicación de Labels

Label Propósito
traefik.enable=true Activa Traefik para este contenedor
Host(\${DOMAIN_HOST}`)` Dominio que responde
entrypoints=web Puerto 80 (HTTP)
entrypoints=websecure Puerto 443 (HTTPS)
tls.certresolver=letsencrypt Solicita certificado SSL automático
loadbalancer.server.port=80 Puerto interno del contenedor
redirect-to-https Middleware para forzar HTTPS

Compose Completo con Traefik

services:
  bookstack:
    container_name: bookstack
    image: lscr.io/linuxserver/bookstack:latest
    restart: unless-stopped
    environment:
      PUID: 1000
      PGID: 1000
      TZ: Europe/Madrid
      APP_URL: https://${DOMAIN_HOST:-bookstack.example.com}
      APP_KEY: ${APP_KEY}
      DB_HOST: bookstack-db
      DB_PORT: 3306
      DB_DATABASE: ${DB_NAME:-bookstack}
      DB_USERNAME: ${DB_USER:-bookstack}
      DB_PASSWORD: ${DB_PASSWORD}
    volumes:
      - bookstack_config:/config
    networks:
      - proxy
      - bookstack-internal
    depends_on:
      - bookstack-db
    labels:
      - traefik.enable=true
      - traefik.http.routers.bookstack-http.rule=Host(`${DOMAIN_HOST}`)
      - traefik.http.routers.bookstack-http.entrypoints=web
      - traefik.http.routers.bookstack-http.middlewares=redirect-to-https
      - traefik.http.routers.bookstack.rule=Host(`${DOMAIN_HOST}`)
      - traefik.http.routers.bookstack.entrypoints=websecure
      - traefik.http.routers.bookstack.tls=true
      - traefik.http.routers.bookstack.tls.certresolver=letsencrypt
      - traefik.http.routers.bookstack.service=bookstack-svc
      - traefik.http.services.bookstack-svc.loadbalancer.server.port=80
      - traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
      - traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true

  bookstack-db:
    container_name: bookstack-db
    image: mariadb:12
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_NAME:-bookstack}
      MYSQL_USER: ${DB_USER:-bookstack}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_RANDOM_ROOT_PASSWORD: 'yes'
    volumes:
      - bookstack_db:/var/lib/mysql
    networks:
      - bookstack-internal

volumes:
  bookstack_config:
    name: bookstack_config
  bookstack_db:
    name: bookstack_db

networks:
  proxy:
    external: true
  bookstack-internal:
    name: bookstack-internal

Troubleshooting

Certificado no se genera

Verificar:

# Logs de Traefik
docker logs traefik | grep bookstack
docker logs traefik | grep -i acme

# DNS correcto
nslookup bookstack.tudominio.com

Soluciones:

  • Verificar que DOMAIN_HOST está configurado
  • DNS debe apuntar correctamente al servidor
  • Puertos 80 y 443 abiertos en firewall
  • Esperar 1-2 minutos para que Let's Encrypt valide

Error 404 Not Found

Causa: Traefik no encuentra el contenedor

Verificar:

# BookStack está en red proxy
docker inspect bookstack | grep -A 5 Networks

# Labels están aplicados
docker inspect bookstack | grep -A 20 Labels

Error 502 Bad Gateway

Causa: BookStack no responde

Soluciones:

# Ver estado de BookStack
docker logs bookstack

# Verificar que MariaDB está lista
docker exec bookstack-db mariadb -u bookstack -p${DB_PASSWORD} -e "SELECT 1"

# Reiniciar
docker restart bookstack-db
sleep 10
docker restart bookstack

Configuración Avanzada

Headers de Seguridad

Añade headers adicionales con middleware:

labels:
  - traefik.http.routers.bookstack.middlewares=bookstack-headers
  - traefik.http.middlewares.bookstack-headers.headers.customResponseHeaders.X-Robots-Tag=none
  - traefik.http.middlewares.bookstack-headers.headers.sslProxyHeaders.X-Forwarded-Proto=https

Limitar Acceso por IP

labels:
  - traefik.http.routers.bookstack.middlewares=bookstack-ipwhitelist
  - traefik.http.middlewares.bookstack-ipwhitelist.ipwhitelist.sourcerange=192.168.1.0/24,10.0.0.0/8

Próximos Pasos

  1. Configuración Inicial - Configurar BookStack
  2. Personalización - LDAP, temas
  3. Backup - Automatiza backups