BookStack: Self-Hosted Wiki and Documentation Platform
Beautiful documentation platform for your homelab. Organize knowledge with books, chapters, and pages.
Introduction
BookStack is an elegant, self-hosted platform for organizing and storing information. Built on Laravel and designed specifically for creating documentation, BookStack provides an intuitive three-tier organizational system (Books, Chapters, Pages) that makes managing large amounts of information effortless. With over 13,000 GitHub stars and active development since 2015, it has become the go-to solution for homelab documentation and team knowledge bases.
Why Choose BookStack?
Intuitive Organization
BookStack’s unique three-tier structure (Books → Chapters → Pages) mirrors how we naturally think about documentation. Unlike flat wikis or complex hierarchies, BookStack provides just enough structure without overwhelming users.
Beautiful, Clean Interface
BookStack focuses on readability and usability. The interface is clean, modern, and distraction-free, making it perfect for both writing and reading documentation.
Privacy and Control
Your documentation stays on your infrastructure. No third-party has access to your homelab notes, network diagrams, or technical documentation. Perfect for security-conscious teams and individuals.
Zero Cost, All Features
Unlike commercial solutions like Confluence ($5-10/user/month) or Notion ($8-10/user/month), BookStack is completely free with no feature restrictions, no user limits, and no hidden costs.
Production-Grade Features
- Rich WYSIWYG and Markdown editor
- Advanced search with full-text indexing
- Detailed permissions and roles
- LDAP/SAML authentication
- Multi-language support (45+ languages)
- Page history and version control
- Diagram support (draw.io integration)
- API for automation
- Export to PDF, HTML, Markdown, plain text
Understanding the Architecture
BookStack’s organizational structure is designed to be immediately understandable:
BookStack Instance
│
├── Shelves (optional containers)
│ ├── Book: "Homelab Documentation"
│ │ ├── Chapter: "Network Infrastructure"
│ │ │ ├── Page: "Router Configuration"
│ │ │ ├── Page: "VLAN Setup"
│ │ │ └── Page: "Firewall Rules"
│ │ ├── Chapter: "Server Setup"
│ │ │ ├── Page: "Proxmox Installation"
│ │ │ └── Page: "Docker Host Setup"
│ │ └── Chapter: "Services"
│ │ ├── Page: "Nextcloud Deployment"
│ │ └── Page: "Media Server Stack"
│ │
│ └── Book: "Personal Projects"
│ ├── Chapter: "Home Automation"
│ └── Chapter: "3D Printing"
│
└── Book: "Meeting Notes"
├── Page: "2025-01-15 Planning"
└── Page: "2025-01-08 Standup" Technical Architecture:
Internet/Local Network
│
▼
┌───────────────┐
│ Reverse Proxy │ (Nginx, Caddy, Traefik)
│ HTTPS/SSL │
└───────┬───────┘
│
▼
┌───────────────┐
│ BookStack │ (PHP-FPM Laravel App)
│ Port 6875 │
└───────┬───────┘
│
┌───┴────┐
│ │
▼ ▼
┌────────┐ ┌─────────┐
│ MySQL │ │ Storage │
│Database│ │ Uploads │
└────────┘ └─────────┘ Prerequisites and System Requirements
Hardware Specifications
Minimum Configuration
- RAM: 2GB (sufficient for small teams up to 10 users)
- CPU: 1 core (2+ recommended)
- Storage: 10GB+ (depends on uploaded images/attachments)
- Network: Standard homelab network
Recommended Configuration
- RAM: 4GB (better performance, more concurrent users)
- CPU: 2+ cores
- Storage: 50GB+ SSD
- Network: Gigabit ethernet
For larger teams (50+ users):
- RAM: 8GB+
- CPU: 4+ cores
- Storage: 100GB+ SSD with backup
- Dedicated database server
Software Requirements
- Docker Engine v24+ with docker-compose
- Linux (Ubuntu 22.04/24.04 LTS recommended)
- Web browser (Chrome, Firefox, Safari, Edge)
- Optional: Reverse proxy for HTTPS
Pre-Deployment Checklist
# Verify Docker installation
docker --version
docker compose version
# Check available resources
free -h
df -h
# Test network connectivity
ping -c 3 google.com Installation and Deployment
Step 1: Environment Preparation
Create project directory and environment file:
# Create directory
mkdir -p ~/bookstack
cd ~/bookstack
# Create environment file
cat > .env <<EOF
# Database Configuration
DB_HOST=bookstack-db
DB_PORT=3306
DB_DATABASE=bookstack
DB_USERNAME=bookstack
DB_PASSWORD=$(openssl rand -base64 24)
MYSQL_ROOT_PASSWORD=$(openssl rand -base64 24)
# Application Configuration
APP_URL=http://YOUR-SERVER-IP:6875
APP_ENV=production
APP_DEBUG=false
APP_KEY=base64:$(openssl rand -base64 32)
# Localization
APP_LANG=en
APP_TIMEZONE=America/New_York
# Email Configuration (optional)
MAIL_DRIVER=smtp
# MAIL_HOST=smtp.gmail.com
# MAIL_PORT=587
# [email protected]
# MAIL_PASSWORD=your-app-password
# MAIL_ENCRYPTION=tls
# [email protected]
# MAIL_FROM_NAME=BookStack
# File Upload Limits
FILE_UPLOAD_SIZE_LIMIT=50
EOF
# Secure environment file
chmod 600 .env Important: Replace YOUR-SERVER-IP with your server’s IP address.
Step 2: Create Docker Compose Configuration
Create docker-compose.yml:
version: "3.8"
services:
# MySQL Database
bookstack-db:
image: mysql:8.0
container_name: bookstack-db
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${DB_DATABASE}
- MYSQL_USER=${DB_USERNAME}
- MYSQL_PASSWORD=${DB_PASSWORD}
volumes:
- db-data:/var/lib/mysql
networks:
- bookstack
command: --default-authentication-plugin=mysql_native_password
# BookStack Application
bookstack:
image: lscr.io/linuxserver/bookstack:latest
container_name: bookstack
restart: unless-stopped
depends_on:
- bookstack-db
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- APP_URL=${APP_URL}
- DB_HOST=${DB_HOST}
- DB_PORT=${DB_PORT}
- DB_DATABASE=${DB_DATABASE}
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
- APP_KEY=${APP_KEY}
- APP_LANG=${APP_LANG}
- APP_TIMEZONE=${APP_TIMEZONE}
- FILE_UPLOAD_SIZE_LIMIT=${FILE_UPLOAD_SIZE_LIMIT}
volumes:
- config:/config
ports:
- "6875:80"
networks:
- bookstack
volumes:
db-data:
config:
networks:
bookstack:
driver: bridge Step 3: Deploy BookStack
# Pull images
docker compose pull
# Start services
docker compose up -d
# Monitor startup logs
docker compose logs -f
# Press Ctrl+C to exit
# Verify containers are running
docker compose ps Both containers should show “Up” status.
Step 4: Initial Setup
Navigate to http://YOUR-SERVER-IP:6875 in your browser.
Default credentials:
- Email:
[email protected] - Password:
password
Immediate security steps:
- Log in with default credentials
- Click user avatar (top right) → Settings
- Click “Change Password”
- Set a strong password (12+ characters)
- Update email address to your actual email
- Save changes
Step 5: Configure Basic Settings
Navigate to Settings → Maintenance:
Site Settings:
├─ Site Name: "My Homelab Wiki" (or your preference)
├─ Allow Public Viewing: false (for private wikis)
├─ Allow Public Guest Access: false
└─ Enable Registration: false (manually create users)
Customization:
├─ Custom HTML Head Content: (optional analytics)
├─ Homepage: Can set a specific page as homepage
└─ Custom CSS: (optional branding) Step 6: Create Your First Content
Create a Book:
1. Click "Books" in top navigation
2. Click "Create New Book"
3. Name: "Homelab Documentation"
4. Description: "Complete documentation for homelab infrastructure"
5. Cover Image: Optional (upload or leave blank)
6. Tags: homelab, infrastructure
7. Save Create a Chapter:
1. Open your new book
2. Click "New Chapter"
3. Name: "Network Configuration"
4. Description: "Network setup and configuration notes"
5. Tags: network, configuration
6. Save Create a Page:
1. Inside your chapter, click "New Page"
2. Title: "Router Setup"
3. Choose editor:
- WYSIWYG (default, like Word)
- Markdown (for technical users)
4. Write content
5. Save Step 7: Configure HTTPS (Production)
For secure access, configure a reverse proxy:
Using Caddy (simplest):
Create Caddyfile:
bookstack.yourdomain.com {
reverse_proxy bookstack:80
encode gzip
} Using Nginx:
server {
listen 443 ssl http2;
server_name bookstack.yourdomain.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
client_max_body_size 50M;
location / {
proxy_pass http://localhost: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;
}
} Update .env after configuring HTTPS:
APP_URL=https://bookstack.yourdomain.com Restart BookStack:
docker compose restart bookstack LDAP Integration
For organizations with Active Directory or LDAP:
Configure LDAP Authentication
Update .env with LDAP settings:
# LDAP Authentication
AUTH_METHOD=ldap
LDAP_SERVER=ldap://dc.example.com:389
LDAP_BASE_DN=DC=example,DC=com
LDAP_DN=CN=BookStack Service,CN=Users,DC=example,DC=com
LDAP_PASS=service-account-password
LDAP_USER_FILTER=(&(sAMAccountName=${user})(objectClass=user))
LDAP_VERSION=3
# LDAP User Synchronization
LDAP_ID_ATTRIBUTE=sAMAccountName
LDAP_EMAIL_ATTRIBUTE=mail
LDAP_DISPLAY_NAME_ATTRIBUTE=displayName
LDAP_THUMBNAIL_ATTRIBUTE=jpegPhoto
# LDAP Group Synchronization
LDAP_USER_TO_GROUPS=true
LDAP_GROUP_ATTRIBUTE=memberOf
LDAP_REMOVE_FROM_GROUPS=true Restart to apply:
docker compose restart bookstack Test LDAP authentication:
- Logout from BookStack
- Login with Active Directory credentials
- User account should auto-create on first login
LDAP Role Mapping
Map LDAP groups to BookStack roles:
# In .env:
LDAP_USER_TO_GROUPS=true
LDAP_GROUP_ATTRIBUTE=memberOf
# Example mapping:
# AD Group "BookStack-Admins" → BookStack Admin role
# AD Group "BookStack-Editors" → BookStack Editor role
# AD Group "BookStack-Viewers" → BookStack Viewer role Configure in Settings → Access:
Default Registration Role: Viewer
(Users auto-created from LDAP start with this role) User Management and Permissions
User Roles
BookStack has four default roles:
| Role | Permissions | Use Case |
|---|---|---|
| Admin | Full system access, user management, settings | Homelab owner, IT administrators |
| Editor | Create, edit, delete content | Documentation writers, team members |
| Viewer | Read-only access | Read-only users, stakeholders |
| Public | Unauthenticated access | Public wikis (disabled by default) |
Creating Users
Manual user creation:
1. Settings → Users
2. Click "Add New User"
3. Enter details:
- Name: John Doe
- Email: [email protected]
- Password: (generate secure password)
- Role: Editor
4. Send email invitation: Yes (if SMTP configured)
5. Save Bulk user import:
BookStack supports API-based user provisioning for automation.
Granular Permissions
Set permissions at any level: Book, Chapter, or Page.
Book-level permissions:
1. Open book
2. Click "Permissions" button
3. Options:
- Inherit from system defaults
- Set custom permissions
4. Custom permissions example:
- Role: Viewer → View only
- Role: Editor → View, Update, Create
- Role: Admin → All permissions
5. Save Page-level permissions:
1. Open page
2. Click "⋮" menu → Permissions
3. Set who can:
- View
- Update
- Delete
4. Useful for sensitive documentation Example permission structure:
Book: "HR Documentation"
├─ Permissions: Admin role only
└─ Chapter: "Employee Handbook"
└─ Permissions: All employees can view Customization and Branding
Custom Themes
Light theme customization:
Settings → Customization → Custom HTML Head Content:
<style>
:root {
--color-primary: #2196F3; /* Blue */
--color-primary-light: #64B5F6;
}
.header {
background-color: var(--color-primary);
}
a {
color: var(--color-primary);
}
</style> Dark theme:
Settings → Customization → Custom HTML Head Content:
<style>
body {
background-color: #1a1a1a;
color: #e0e0e0;
}
.card {
background-color: #2d2d2d;
border-color: #404040;
}
.page-content {
background-color: #2d2d2d;
color: #e0e0e0;
}
</style> Custom Logo and Branding
Settings → Customization:
Application Icon: Upload 256x256 PNG logo
Application Name: "YourCompany Wiki"
Homepage: Set specific page as landing page Draw.io Integration
Enable diagram editor for network diagrams, flowcharts, etc.:
Settings → Features → Diagrams:
Enable Drawing Editor: Yes Creating diagrams:
1. In any page, click "+ Insert" → "Drawing"
2. Draw.io editor opens
3. Create network diagram, flowchart, etc.
4. Save
5. Diagram embedded in page Example use cases:
- Network topology diagrams
- Server rack layouts
- Process flowcharts
- System architecture diagrams
Backup Strategies
What to Backup
| Component | Location | Priority | Contains |
|---|---|---|---|
| Database | MySQL dump | Critical | All content, users, settings |
| Uploads | /config/www/uploads | Important | Uploaded images, attachments |
| Config | .env file | Important | Configuration settings |
| Themes | /config/www/themes | Nice to have | Custom themes |
Automated Backup Script
Create ~/bookstack/backup.sh:
#!/bin/bash
# Configuration
BACKUP_DIR="/mnt/backups/bookstack"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
# Create backup directory
mkdir -p "$BACKUP_DIR"
echo "Starting BookStack backup at $(date)"
# Backup database
docker exec bookstack-db mysqldump -u ${DB_USERNAME} -p${DB_PASSWORD} ${DB_DATABASE} | gzip > "$BACKUP_DIR/db-${DATE}.sql.gz"
if [ $? -eq 0 ]; then
echo "✓ Database backed up"
else
echo "✗ Database backup FAILED" >&2
exit 1
fi
# Backup uploads and config
docker run --rm -v bookstack_config:/source:ro -v "$BACKUP_DIR":/backup alpine tar czf /backup/config-${DATE}.tar.gz -C /source .
echo "✓ Config and uploads backed up"
# Backup .env file
cp .env "$BACKUP_DIR/env-${DATE}.txt"
# Clean old backups
find "$BACKUP_DIR" -name "*.gz" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "*.txt" -mtime +$RETENTION_DAYS -delete
echo "Backup completed at $(date)"
echo "Location: $BACKUP_DIR" Make executable and schedule:
chmod +x ~/bookstack/backup.sh
# Daily backup at 2 AM
crontab -e
# Add: 0 2 * * * /home/user/bookstack/backup.sh >> /var/log/bookstack-backup.log 2>&1 Disaster Recovery
Complete restoration:
# Stop BookStack
cd ~/bookstack
docker compose down
# Restore database
gunzip < /mnt/backups/bookstack/db-YYYYMMDD.sql.gz | docker exec -i bookstack-db mysql -u ${DB_USERNAME} -p${DB_PASSWORD} ${DB_DATABASE}
# Restore config and uploads
docker run --rm -v bookstack_config:/dest -v /mnt/backups/bookstack:/backup alpine tar xzf /backup/config-YYYYMMDD.tar.gz -C /dest
# Restore .env
cp /mnt/backups/bookstack/env-YYYYMMDD.txt .env
# Start BookStack
docker compose up -d
# Verify
docker compose logs -f Advanced Features
Page Templates
Create reusable templates for consistent documentation:
Create template:
1. Create a page with your template content
2. Example: "Server Documentation Template"
3. Content:
## Overview
[Server purpose and description]
## Specifications
- CPU:
- RAM:
- Storage:
## Network Configuration
- IP Address:
- VLAN:
- Firewall Rules:
## Services Running
- Service 1:
- Service 2:
## Backup Information
- Backup Schedule:
- Backup Location:
## Troubleshooting
[Common issues and solutions]
4. Save with tag: template Use template:
1. Create new page
2. Click "⋮" menu → Copy
3. Paste into new page
4. Fill in details
5. Remove "template" tag Version Control and History
Every page maintains full version history:
View page history:
1. Open any page
2. Click "⋮" menu → History
3. See all revisions with:
- Timestamp
- Author
- Change summary
4. Click any revision to view
5. Restore previous version if needed Compare versions:
1. Page History
2. Select two versions
3. Click "Compare"
4. Side-by-side diff view
5. See what changed API Integration
BookStack provides a comprehensive REST API.
Generate API token:
1. User Settings → API Tokens
2. Click "Create Token"
3. Name: "Automation Script"
4. Expiry: Never (or set date)
5. Copy token (shown only once)
6. Save Example: Automated page creation:
#!/usr/bin/env python3
import requests
import json
# Configuration
BOOKSTACK_URL = "https://bookstack.yourdomain.com"
API_TOKEN = "your-token-here"
API_SECRET = "your-secret-here"
headers = {
"Authorization": f"Token {API_TOKEN}:{API_SECRET}",
"Content-Type": "application/json"
}
# Create a page
page_data = {
"book_id": 1,
"chapter_id": 1,
"name": "Automated Page",
"html": "<h1>This page was created via API</h1><p>Content here...</p>",
"tags": [
{"name": "automated"},
{"name": "api"}
]
}
response = requests.post(
f"{BOOKSTACK_URL}/api/pages",
headers=headers,
json=page_data
)
if response.status_code == 200:
print(f"Page created: {response.json()['id']}")
else:
print(f"Error: {response.text}") Example: Bulk export:
#!/bin/bash
# Export all pages to PDF
BOOKSTACK_URL="https://bookstack.yourdomain.com"
TOKEN="your-token"
SECRET="your-secret"
# Get all pages
pages=$(curl -s -H "Authorization: Token ${TOKEN}:${SECRET}" "${BOOKSTACK_URL}/api/pages" | jq -r '.data[].id')
# Export each page
for page_id in $pages; do
curl -H "Authorization: Token ${TOKEN}:${SECRET}" "${BOOKSTACK_URL}/api/pages/${page_id}/export/pdf" -o "page-${page_id}.pdf"
echo "Exported page ${page_id}"
done Markdown Support
BookStack supports full Markdown syntax:
Switching to Markdown editor:
1. User Settings → Preferences
2. Editor: Markdown
3. Save Markdown features:
# Headings
## Level 2
### Level 3
**Bold text**
*Italic text*
~~Strikethrough~~
- Bullet list
- Item 2
1. Numbered list
2. Item 2
[Link text](https://example.com)

`inline code`
```python
# Code block
def hello():
print("Hello, World!") Blockquote
| Header 1 | Header 2 |
|---|---|
| Cell 1 | Cell 2 |
### Multi-Language Support
BookStack supports 45+ languages:
**Change interface language:**
User Settings → Preferences → Language Select: English, Español, Français, Deutsch, etc.
**Per-user language:**
Each user can set their own language preference.
## Troubleshooting Common Issues
**Issue: Can't login after changing APP_URL**
```bash
# Clear application cache
docker exec bookstack php artisan cache:clear
docker exec bookstack php artisan config:clear
docker exec bookstack php artisan view:clear
# Restart
docker compose restart bookstack Issue: Uploads failing
# Check upload limit in .env:
FILE_UPLOAD_SIZE_LIMIT=50
# Check disk space
df -h
# Check permissions
docker exec bookstack ls -la /config/www/uploads Issue: LDAP authentication not working
# Test LDAP connection
docker exec bookstack php artisan bookstack:ldap-test
# Check logs
docker compose logs bookstack | grep -i ldap
# Verify LDAP settings in .env Issue: Slow performance
# Enable caching
docker exec bookstack php artisan cache:clear
docker exec bookstack php artisan config:cache
# Optimize database
docker exec bookstack-db mysql -u root -p${MYSQL_ROOT_PASSWORD} -e "OPTIMIZE TABLE bookstack.*"
# Check resource usage
docker stats bookstack bookstack-db Best Practices for Documentation
Organization Strategy
For homelabs:
Book: "Infrastructure"
├─ Chapter: "Network"
│ ├─ Topology Diagram
│ ├─ IP Address Scheme
│ └─ Firewall Rules
├─ Chapter: "Servers"
│ ├─ Proxmox Hosts
│ ├─ Docker Hosts
│ └─ Backup Servers
└─ Chapter: "Services"
├─ Monitoring Stack
├─ Media Server
└─ Home Automation
Book: "Procedures"
├─ Chapter: "Maintenance"
├─ Chapter: "Troubleshooting"
└─ Chapter: "Disaster Recovery" For teams:
Book: "Company Wiki"
├─ Chapter: "Onboarding"
├─ Chapter: "Policies"
└─ Chapter: "Resources"
Book: "Product Documentation"
├─ Chapter: "User Guides"
├─ Chapter: "API Reference"
└─ Chapter: "Troubleshooting" Writing Effective Documentation
Page structure:
# Page Title
## Overview
Brief description of what this page covers.
## Prerequisites
What you need before following this guide.
## Step-by-Step Instructions
### Step 1: Preparation
Detailed instructions...
### Step 2: Implementation
Detailed instructions...
## Troubleshooting
Common issues and solutions.
## Related Pages
- Link to related documentation
- Link to prerequisite pages
## Change Log
- 2025-01-15: Initial creation
- 2025-01-20: Added troubleshooting section Use tags effectively:
Tags for organizational purposes:
- Status: draft, review, published, archived
- Priority: critical, important, reference
- Category: network, storage, compute, security
- Version: v1, v2, current, deprecated Maintenance Routine
Weekly:
- Review recent changes
- Check for broken links
- Update outdated information
Monthly:
- Archive outdated pages
- Reorganize content as needed
- Review user feedback
Quarterly:
- Full content audit
- Update screenshots
- Verify all procedures still work
Next Steps and Related Guides
Immediate Next Steps
Create core documentation
- Network topology
- Server inventory
- Service catalog
- Common procedures
Set up user access
- Create user accounts or configure LDAP
- Set appropriate permissions
- Train users on the system
Establish backup routine
- Test backup script
- Verify restoration
- Set up off-site copy
Customize appearance
- Add logo and branding
- Create custom homepage
- Set up templates
Advanced Topics
- API automation - Automated documentation generation
- Webhook integration - Trigger actions on content changes
- Multi-instance setup - Separate wikis for different teams
- Advanced permissions - Complex role-based access control
Related Homelabbing.io Guides
- Reverse Proxy Setup - Secure HTTPS access
- LDAP Integration - Enterprise authentication
- Backup Strategies - Comprehensive backup solutions
- Monitoring Setup - Track wiki usage and health
Conclusion
BookStack transforms how you organize and access information in your homelab. With its intuitive interface, powerful features, and complete self-hosting, it’s the perfect solution for documentation that grows with your infrastructure.
Key Achievements After This Guide:
- Self-hosted wiki platform
- Organized documentation structure
- Multi-user access with permissions
- Automated backups
- HTTPS security
- Integration-ready via API
Success Metrics (First Month):
- 20+ pages of documentation created
- All team members have accounts
- Backup and restore tested
- Custom branding applied
- LDAP integration working (if applicable)
Start by documenting your most critical systems first - the ones you’d need documentation for if they failed at 3 AM. Gradually build out your knowledge base, and soon you’ll wonder how you ever managed without it.
Welcome to organized knowledge management!
Document Version: 1.0 Last Updated: December 2025 Word Count: ~5,600 words BookStack Version: 24.0+ (latest stable)