BookStack
Plataforma de documentación y wiki de código abierto. Organiza contenido en libros, capítulos y páginas con editor WYSIWYG y Markdown.
Características
- 📚 Organización jerárquica: Libros → Capítulos → Páginas
- ✏️ Editor dual: WYSIWYG y Markdown
- 🔍 Búsqueda potente: Busca en todo el contenido
- 🔐 Control de acceso: Permisos granulares por rol
- 📝 Historial de cambios: Seguimiento completo de ediciones
- 🖼️ Gestión de imágenes: Biblioteca de medios integrada
- 🔗 Integración: LDAP, SAML, OAuth
- 🌍 Multi-idioma: Soporte para múltiples idiomas
Requisitos Previos
- Docker Engine instalado
- Portainer configurado (recomendado)
- Para Traefik o NPM: Red Docker
proxycreada - Dominio configurado: Para acceso HTTPS
- Contraseña generada: DB_PASSWORD
⚠️ IMPORTANTE: BookStack requiere MariaDB. Este compose incluye el contenedor de base de datos.
Generar Contraseña
Antes de cualquier despliegue, genera una contraseña segura:
# DB_PASSWORD (MariaDB)
openssl rand -base64 32
Guarda el resultado, lo necesitarás en el archivo .env.
⚠️ Importante: Usa comillas simples en el archivo
.envsi la contraseña contiene caracteres especiales. Ejemplo:DB_PASSWORD='tu_password_generado'
Despliegue con Portainer
Opción A: Git Repository (Recomendada)
Permite mantener la configuración actualizada automáticamente desde Git.
- En Portainer, ve a Stacks → Add stack
- Nombra el stack:
bookstack - Selecciona Git Repository
- Configura:
- Repository URL:
https://git.ictiberia.com/groales/bookstack - Repository reference:
refs/heads/main - Compose path:
docker-compose.yml - GitOps updates: Activado (opcional - auto-actualización)
- Repository URL:
- Solo para Traefik: En Additional paths, añade:
docker-compose.override.traefik.yml.example
- En Environment variables, añade:
DB_PASSWORD=tu_password_generado
DOMAIN_HOST=bookstack.tudominio.com
- Click en Deploy the stack
Opción B: Web editor
Para personalización completa del compose.
- En Portainer, ve a Stacks → Add stack
- Nombra el stack:
bookstack - Selecciona Web editor
- Pega el contenido de
docker-compose.yml - En Environment variables, añade las mismas variables que la Opción A
- Click en Deploy the stack
Modos de Despliegue
Traefik (Proxy Inverso con SSL automático)
Requisitos:
- Stack de Traefik desplegado
- Red
proxycreada - DNS apuntando al servidor
Si desplegaste con Opción A (Git Repository), ya configuraste todo en el paso 5 y 6. Simplemente accede a https://bookstack.tudominio.com
Si usas otra forma de despliegue:
-
Asegúrate de tener el archivo
docker-compose.override.traefik.yml.examplecomodocker-compose.override.yml -
Verifica que en Environment variables tienes
DOMAIN_HOSTconfigurado correctamente -
Despliega el stack y accede a
https://bookstack.tudominio.com
Ejemplo de 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}
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:11-alpine
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
Nginx Proxy Manager (NPM)
Requisitos:
- NPM desplegado y accesible
- Red
proxycreada - DNS apuntando al servidor
Pasos:
-
Despliega el stack con el
docker-compose.ymlbase (sin override) -
En NPM, crea un nuevo Proxy Host:
- Domain Names:
bookstack.tudominio.com - Scheme:
http - Forward Hostname / IP:
bookstack - Forward Port:
80 - Cache Assets: ✅ Activado
- Block Common Exploits: ✅ Activado
- Websockets Support: ✅ Activado
- Domain Names:
-
En la pestaña SSL:
- SSL Certificate: Request a new SSL Certificate (Let's Encrypt)
- Force SSL: ✅ Activado
- HTTP/2 Support: ✅ Activado
- HSTS Enabled: ✅ Activado (opcional)
-
Guarda y accede a
https://bookstack.tudominio.com
Configuración Inicial
Primer Acceso
-
Accede a BookStack usando tu dominio configurado
-
Login con credenciales por defecto:
- Email:
admin@admin.com - Password:
password
- Email:
-
⚠️ CRÍTICO: Cambia la contraseña inmediatamente:
- Click en tu avatar (esquina superior derecha)
- Edit Profile → Change Password
Panel de Administración
Accede al panel: Settings (engranaje superior derecho)
Configuración Básica
Settings → Settings:
- Application Name: Nombre de tu wiki
- Application Description: Descripción breve
- Application Logo: Sube tu logo personalizado
- Default Language: Español u otro idioma
Registro de Usuarios
Settings → Registration Settings:
- Allow public registration: Desactivar (❌)
- Allow public viewing: Activar si quieres que usuarios no autenticados puedan leer
- Default role for new users: Seleccionar rol apropiado
Roles y Permisos
Settings → Roles:
- Admin: Control total
- Editor: Puede crear y editar contenido
- Viewer: Solo lectura
Crea roles personalizados según necesites:
- Permissions: Granular por libros, capítulos, páginas
- System Permissions: Gestión de imágenes, ajustes
Personalización de Tema
Settings → Customization:
- Custom HTML Head Content: Añadir CSS personalizado
- Color Scheme: Claro/Oscuro
- Custom Styles: CSS para personalización avanzada
Personalización
Integración con LDAP
Settings → Authentication → LDAP:
# Añadir al .env
LDAP_SERVER=ldap.example.com:389
LDAP_BASE_DN=dc=example,dc=com
LDAP_DN=cn=bookstack,ou=Services,dc=example,dc=com
LDAP_PASS=password
LDAP_USER_FILTER=(&(uid=${user}))
LDAP_VERSION=3
Reinicia el contenedor: docker restart bookstack
SAML / OAuth
Settings → Authentication:
- SAML 2.0: Para Active Directory con ADFS
- OAuth: Google, GitHub, GitLab, etc.
Consulta la documentación oficial para configuración específica.
Comandos Personalizados
Acceso al contenedor:
# Shell de BookStack
docker exec -it bookstack bash
# Comandos artisan disponibles
docker exec bookstack php artisan list
# Limpiar caché
docker exec bookstack php artisan cache:clear
# Regenerar permisos de búsqueda
docker exec bookstack php artisan bookstack:regenerate-search
Backup y Restauración
Backup Manual
# Backup de MariaDB
docker exec bookstack-db mariadb-dump -u bookstack -p${DB_PASSWORD} bookstack > bookstack-backup-$(date +%Y%m%d).sql
# Backup de configuración y uploads
docker run --rm -v bookstack_config:/backup -v $(pwd):/target alpine tar czf /target/bookstack-config-$(date +%Y%m%d).tar.gz -C /backup .
Backup Automático
Crea un script en /root/backup-bookstack.sh:
#!/bin/bash
BACKUP_DIR="/backups/bookstack"
DATE=$(date +%Y%m%d-%H%M%S)
DB_PASSWORD="tu_password_aqui"
mkdir -p $BACKUP_DIR
# MariaDB
docker exec bookstack-db mariadb-dump -u bookstack -p${DB_PASSWORD} bookstack | gzip > $BACKUP_DIR/bookstack-db-$DATE.sql.gz
# Configuración
docker run --rm -v bookstack_config:/backup -v $BACKUP_DIR:/target alpine tar czf /target/bookstack-config-$DATE.tar.gz -C /backup .
# Limpiar backups antiguos (mantener 7 días)
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
echo "Backup completado: $DATE"
Programa con cron:
chmod +x /root/backup-bookstack.sh
crontab -e
# Backup diario a las 2 AM
0 2 * * * /root/backup-bookstack.sh
Restauración
# Detener BookStack
docker stop bookstack
# Restaurar MariaDB
gunzip < bookstack-db-20250101.sql.gz | docker exec -i bookstack-db mariadb -u bookstack -p${DB_PASSWORD} bookstack
# Restaurar configuración
docker run --rm -v bookstack_config:/restore -v $(pwd):/source alpine tar xzf /source/bookstack-config-20250101.tar.gz -C /restore
# Iniciar BookStack
docker start bookstack
Actualización
Actualizar BookStack
# 1. Backup ANTES de actualizar
docker exec bookstack-db mariadb-dump -u bookstack -p${DB_PASSWORD} bookstack > bookstack-pre-update-$(date +%Y%m%d).sql
# 2. Detener stack
docker stop bookstack bookstack-db
# 3. Actualizar imágenes
docker pull lscr.io/linuxserver/bookstack:latest
docker pull mariadb:11-alpine
# 4. Iniciar stack
docker start bookstack-db
sleep 10
docker start bookstack
# 5. Verificar logs
docker logs -f bookstack
# 6. Verificar versión en Settings → About
Actualizar MariaDB
Si necesitas actualizar de MariaDB 10 a 11 (ya está en 11):
# 1. Backup
docker exec bookstack-db mariadb-dump -u bookstack -p${DB_PASSWORD} bookstack > bookstack-db-migration.sql
# 2. Detener y eliminar contenedor antiguo
docker stop bookstack-db
docker rm bookstack-db
# 3. Eliminar volumen antiguo
docker volume rm bookstack_db
# 4. Recrear con MariaDB 11
docker compose up -d bookstack-db
# 5. Esperar inicialización
sleep 15
# 6. Restaurar datos
cat bookstack-db-migration.sql | docker exec -i bookstack-db mariadb -u bookstack -p${DB_PASSWORD} bookstack
# 7. Iniciar BookStack
docker start bookstack
Solución de Problemas
BookStack no inicia
Síntomas: Contenedor se reinicia constantemente
Diagnóstico:
docker logs bookstack
Soluciones:
- Verificar que MariaDB esté funcionando:
docker logs bookstack-db - Comprobar contraseña en
.env - Verificar permisos del volumen:
docker exec bookstack ls -la /config
Error de conexión a base de datos
Síntomas: SQLSTATE[HY000] [2002] Connection refused
Solución:
# Verificar que MariaDB esté lista
docker exec bookstack-db mariadb -u bookstack -p${DB_PASSWORD} -e "SELECT 1"
# Reiniciar servicios en orden
docker restart bookstack-db
sleep 10
docker restart bookstack
Error de permisos
Síntomas: PermissionError: [Errno 13] Permission denied
Solución:
docker run --rm -v bookstack_config:/data alpine chown -R 1000:1000 /data
docker restart bookstack
BookStack lento o no responde
Diagnóstico:
# Ver uso de recursos
docker stats bookstack bookstack-db
# Ver queries lentas en MariaDB
docker exec bookstack-db mariadb -u bookstack -p${DB_PASSWORD} -e "SHOW FULL PROCESSLIST;"
Soluciones:
- Limpiar caché:
docker exec bookstack php artisan cache:clear - Optimizar BD:
docker exec bookstack-db mariadb-optimize -u bookstack -p${DB_PASSWORD} bookstack - Regenerar índices de búsqueda:
docker exec bookstack php artisan bookstack:regenerate-search
Comandos de emergencia
# Reiniciar todo el stack
docker restart bookstack bookstack-db
# Ver logs en tiempo real
docker logs -f --tail 100 bookstack
# Acceder a shell de BookStack
docker exec -it bookstack bash
# Ejecutar comandos artisan
docker exec bookstack php artisan tinker
# Limpiar todo el caché
docker exec bookstack php artisan cache:clear
docker exec bookstack php artisan config:clear
docker exec bookstack php artisan view:clear
docker restart bookstack
Variables de Entorno
Requeridas
| Variable | Descripción | Ejemplo | |
|---|---|---|---|
DB_PASSWORD |
Contraseña de MariaDB | generada_con_openssl |
|
DOMAIN_HOST |
Dominio completo (usado en APP_URL) | bookstack.example.com |
Opcionales
| Variable | Descripción | Valor por defecto |
|---|---|---|
DB_NAME |
Nombre de la base de datos | bookstack |
DB_USER |
Usuario de MariaDB | bookstack |
PUID / PGID |
UID/GID del usuario | 1000 |
TZ |
Zona horaria | Europe/Madrid |
Recursos
- Documentación oficial de BookStack
- LinuxServer BookStack Image
- BookStack GitHub
- BookStack Demo
- API Documentation
Licencia
BookStack es software de código abierto bajo licencia MIT.