BookStack is a self-hosted documentation platform with an intuitive structure borrowed from the physical world: Shelves → Books → Chapters → Pages. Non-technical colleagues understand it instantly, and it comes with a WYSIWYG editor (or Markdown), page revisions, search, permissions, diagrams via draw.io, and exports to PDF and HTML.
It’s a Laravel (PHP) application with MySQL/MariaDB — light enough for a small VPS.
1. Run BookStack with Docker Compose
The widely used LinuxServer.io image packages BookStack with Nginx and PHP:
mkdir -p ~/bookstack && cd ~/bookstack
compose.yaml:
services:
bookstack:
image: lscr.io/linuxserver/bookstack:latest
restart: unless-stopped
environment:
PUID: "1000"
PGID: "1000"
TZ: Etc/UTC
APP_URL: https://docs.example.com
APP_KEY: ${APP_KEY}
DB_HOST: db
DB_PORT: "3306"
DB_USERNAME: bookstack
DB_PASSWORD: ${DB_PASSWORD}
DB_DATABASE: bookstack
volumes:
- ./config:/config
ports:
- "127.0.0.1:6875:80"
depends_on:
- db
db:
image: lscr.io/linuxserver/mariadb:latest
restart: unless-stopped
environment:
PUID: "1000"
PGID: "1000"
TZ: Etc/UTC
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: bookstack
MYSQL_USER: bookstack
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- ./db:/config
Generate secrets. APP_KEY must be a Laravel key in base64: format:
cat > .env <<EOF
APP_KEY=base64:$(openssl rand -base64 32)
DB_PASSWORD=$(openssl rand -hex 16)
DB_ROOT_PASSWORD=$(openssl rand -hex 16)
EOF
chmod 600 .env
docker compose up -d
Check the image documentation for current variable names; some versions differ.
APP_URL must exactly match the URL users visit — BookStack uses it to build links and assets. Getting it wrong is the most common cause of broken styling or redirect loops.
2. HTTPS reverse proxy
server {
listen 80;
server_name docs.example.com;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:6875;
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;
}
}
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d docs.example.com
3. Change the default login
Log in at https://docs.example.com with the default account: [email protected] / password. Immediately change the email and password (My Account), and enable multi-factor authentication.
4. Organise content
- Shelves — top-level groups (e.g. “Engineering”, “HR”, “Customer Support”).
- Books — a topic (e.g. “Server Runbooks”).
- Chapters — sections within a book (optional).
- Pages — the actual content.
Tags, templates (Settings → Customization → Page templates) and cross-links help as the library grows.
5. Permissions and roles
Settings → Roles define what users can do system-wide; each shelf, book, chapter or page can override permissions for specific roles. Typical setup: Admin, Editor, Viewer roles; sensitive books visible only to certain roles.
Disable public registration (Settings → Registration) unless you want it. Optionally allow public (guest) viewing for specific books — useful for public product docs.
6. Single sign-on
BookStack supports OIDC, SAML 2.0 and LDAP via environment variables, for example OIDC:
AUTH_METHOD: oidc
OIDC_NAME: "Company SSO"
OIDC_DISPLAY_NAME_CLAIMS: name
OIDC_CLIENT_ID: bookstack
OIDC_CLIENT_SECRET: ${OIDC_SECRET}
OIDC_ISSUER: https://auth.example.com/application/o/bookstack/
OIDC_ISSUER_DISCOVER: "true"
Pair it with Authentik or Keycloak.
7. Email
Notifications, invitations and password resets need SMTP:
MAIL_DRIVER: smtp
MAIL_HOST: smtp.example.com
MAIL_PORT: "587"
MAIL_ENCRYPTION: tls
MAIL_USERNAME: [email protected]
MAIL_PASSWORD: ${MAIL_PASSWORD}
MAIL_FROM: [email protected]
8. Backups
Back up the database and uploaded files:
docker compose exec db mariadb-dump -u bookstack -p"$(grep DB_PASSWORD .env | cut -d= -f2)" bookstack | gzip > bookstack-$(date +%F).sql.gz
tar czf bookstack-files-$(date +%F).tar.gz config/www/uploads config/www/files config/www/images 2>/dev/null
Paths inside ./config depend on the image version — verify where uploads live. Keep .env (the APP_KEY) with your backups; it’s needed to decrypt some stored data.
9. Updates
docker compose pull && docker compose up -d
Database migrations run automatically on startup.
BookStack vs Wiki.js
BookStack is opinionated and easy for everyone; Wiki.js is more flexible and developer-oriented (Git sync, Markdown files). Both run happily on a small Docker VPS.