Overview
BookStack is a free, open-source platform for organizing and storing information. It uses a simple and intuitive organizational structure based on real-world concepts: Shelves contain Books, Books contain Chapters, and Chapters contain Pages. This familiar hierarchy makes it easy for teams to organize documentation and knowledge bases.
BookStack is built with PHP (Laravel framework) and supports MySQL/MariaDB. It features a WYSIWYG editor, Markdown editing, full-text search, role-based permissions, LDAP/SAML/OIDC authentication, multi-language support, API access, and customizable theming.
Installation
Docker (Recommended)
# docker-compose.yml
version: '3'
services:
bookstack:
image: lscr.io/linuxserver/bookstack:latest
container_name: bookstack
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- APP_URL=https://wiki.example.com
- DB_HOST=bookstack_db
- DB_PORT=3306
- DB_USER=bookstack
- DB_PASS=changeme
- DB_DATABASE=bookstack
volumes:
- ./bookstack_data:/config
ports:
- "8080:80"
depends_on:
- bookstack_db
restart: unless-stopped
bookstack_db:
image: mariadb:10.11
container_name: bookstack_db
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=bookstack
- MYSQL_USER=bookstack
- MYSQL_PASSWORD=changeme
volumes:
- ./bookstack_db:/var/lib/mysql
restart: unless-stopped
docker compose up -d
# Default login: admin@admin.com / password
Ubuntu/Debian Manual Install
# Install dependencies
sudo apt update
sudo apt install -y git unzip nginx php8.2-fpm php8.2-mbstring \
php8.2-xml php8.2-mysql php8.2-gd php8.2-curl php8.2-ldap \
mariadb-server composer
# Create database
sudo mysql -e "CREATE DATABASE bookstack;"
sudo mysql -e "CREATE USER 'bookstack'@'localhost' IDENTIFIED BY 'changeme';"
sudo mysql -e "GRANT ALL PRIVILEGES ON bookstack.* TO 'bookstack'@'localhost';"
# Clone and install BookStack
cd /var/www
sudo git clone https://github.com/BookStackApp/BookStack.git --branch release
cd BookStack
sudo composer install --no-dev
sudo cp .env.example .env
sudo php artisan key:generate
# Edit .env with database credentials then run migrations
sudo php artisan migrate
Content Organization
Hierarchy
| Level | Description | Analogy |
|---|
| Shelf | Groups related books | Bookshelf / Category |
| Book | Collection of related content | Book / Project |
| Chapter | Logical grouping within a book | Section / Module |
| Page | Individual document | Article / Document |
Editor Features
WYSIWYG Editor
| Feature | How To |
|---|
| Headings | Format dropdown |
| Bold/Italic | Ctrl+B / Ctrl+I |
| Lists | Toolbar buttons |
| Links | Ctrl+K or toolbar |
| Images | Drag-drop, paste, or upload |
| Tables | Insert then Table |
| Code blocks | Insert then Code Block |
| Callouts | Insert then Callout |
| Drawing | Insert then Drawing |
Markdown Editor
Switch to Markdown mode in user preferences for full Markdown support including headings, bold, italic, lists, links, images, tables, code blocks, and block quotes.
Callout Blocks
<p class="callout info">Info callout.</p>
<p class="callout warning">Warning callout.</p>
<p class="callout danger">Danger callout.</p>
<p class="callout success">Success callout.</p>
Configuration
Environment Variables (.env)
# Application
APP_URL=https://wiki.example.com
# Database
DB_HOST=localhost
DB_DATABASE=bookstack
DB_USERNAME=bookstack
DB_PASSWORD=changeme
# Mail
MAIL_DRIVER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_ENCRYPTION=tls
# Authentication
AUTH_METHOD=standard # standard, ldap, saml2, oidc
# LDAP
LDAP_SERVER=ldap://ldap.example.com:389
LDAP_BASE_DN=dc=example,dc=com
LDAP_USER_FILTER=(&(uid=${user}))
# OIDC
OIDC_NAME=SSO Login
OIDC_CLIENT_ID=bookstack
OIDC_CLIENT_SECRET=secret
OIDC_ISSUER=https://auth.example.com
OIDC_ISSUER_DISCOVER=true
# Storage
STORAGE_TYPE=local # local, local_secure, s3
# Registration
REGISTRATION_ENABLED=false
Permissions
Role-Based Access
| Default Role | Permissions |
|---|
| Admin | Full access to everything |
| Editor | Create, edit, delete own content |
| Viewer | Read-only access |
Permission Levels
| Level | Scope |
|---|
| System | Global role permissions |
| Shelf | Per-shelf overrides |
| Book | Per-book overrides |
| Chapter | Per-chapter overrides |
| Page | Per-page overrides |
Search
Search Syntax
| Syntax | Description |
|---|
keyword | Basic text search |
"exact phrase" | Exact phrase match |
{in:name} | Search in names |
{in:body} | Search in content body |
{type:page} | Filter by content type |
{type:book} | Books only |
{created_by:me} | Items you created |
[tag_name] | Filter by tag |
[tag_name=value] | Filter by tag with value |
API
# List books
curl -H "Authorization: Token ID:SECRET" \
https://wiki.example.com/api/books
# Get a specific page
curl -H "Authorization: Token ID:SECRET" \
https://wiki.example.com/api/pages/42
# Create a page
curl -X POST \
-H "Authorization: Token ID:SECRET" \
-H "Content-Type: application/json" \
https://wiki.example.com/api/pages \
-d '{"book_id": 1, "name": "New Page", "html": "<p>Content</p>"}'
# Search
curl -H "Authorization: Token ID:SECRET" \
"https://wiki.example.com/api/search?query=docker"
# Export page as PDF
curl -H "Authorization: Token ID:SECRET" \
https://wiki.example.com/api/pages/42/export/pdf -o page.pdf
# Export page as Markdown
curl -H "Authorization: Token ID:SECRET" \
https://wiki.example.com/api/pages/42/export/markdown
Advanced Usage
Custom Theming
mkdir -p /var/www/BookStack/themes/my-theme
# Custom CSS
cat > themes/my-theme/custom-styles.css << 'EOF'
:root {
--color-primary: #1a73e8;
}
.header { background-color: #1a1a2e; }
EOF
# Set in .env
APP_THEME=my-theme
Webhooks
| Event | Description |
|---|
page_create | New page created |
page_update | Page content modified |
page_delete | Page removed |
book_create | New book created |
comment_create | New comment added |
Backup and Restore
# Backup database
mysqldump -u bookstack -p bookstack > bookstack_backup.sql
# Backup files
tar -czf bookstack_files.tar.gz \
/var/www/BookStack/storage/uploads \
/var/www/BookStack/public/uploads \
/var/www/BookStack/.env
# Restore
mysql -u bookstack -p bookstack < bookstack_backup.sql
tar -xzf bookstack_files.tar.gz -C /
Troubleshooting
| Issue | Solution |
|---|
| 500 error after install | Check permissions; run php artisan key:generate |
| LDAP login failing | Verify LDAP filter syntax; test with ldapsearch |
| Images not uploading | Check storage/uploads permissions; increase PHP upload limits |
| Search not finding content | Run php artisan bookstack:regenerate-search |
| Email not sending | Verify SMTP settings; check mail logs |
| Slow performance | Enable OPcache; optimize MySQL; add Redis |
| After update errors | Run composer install --no-dev && php artisan migrate |
| PDF export issues | Install wkhtmltopdf for better PDF rendering |