BookStack
Collaboration Tool
BookStack
Overview
BookStack is a simple, self-hosted, easy-to-use platform for organizing and storing information. It's fully free and open source, MIT licensed software. Based on the concept of books, BookStack provides an intuitive hierarchical structure that makes it easy to create and manage documentation, making it ideal for knowledge sharing within teams and organizations.
Details
BookStack organizes information into four hierarchical levels: Shelves, Books, Chapters, and Pages. It provides both WYSIWYG and Markdown editors with live preview capabilities, and includes built-in diagram creation through diagrams.net integration. With fully searchable content, multi-language support, flexible permission management, and a REST API for programmatic access, BookStack offers comprehensive documentation capabilities. Built using PHP on the Laravel framework with MySQL for data storage, it can run efficiently even on modest hardware.
Key Features
- Hierarchical Organization: Four-level structure with shelves, books, chapters, and pages
- Dual Editors: WYSIWYG and Markdown editors with live preview
- Diagram Creation: Built-in diagrams.net integration
- Powerful Search: Full-text search at book level or across all content
- Version Control: Page history and revision tracking
- Permission Management: Role-based access control (Viewer, Editor, Admin)
- Authentication Options: Email/password, social logins, SAML2, LDAP support
- Customization: Customizable logo, name, and themes (light/dark)
API Overview
REST API Basic Structure
GET https://example.com/api/books
Authorization: Token {id}:{secret}
Content-Type: application/json
Key Endpoints
# List all books
GET /api/books
# Create a new page
POST /api/pages
{
"book_id": 1,
"name": "New Page",
"html": "<p>Page content</p>"
}
# Update a page
PUT /api/pages/{id}
{
"name": "Updated Page",
"html": "<p>Updated content</p>"
}
Advantages and Disadvantages
Advantages
- Completely free and open source (MIT license)
- Simple and intuitive user interface
- Self-hosted with full data control
- Lightweight and fast (runs on $5 VPS)
- Multi-language support (including Japanese, French, German, etc.)
- Flexible authentication options
- Extensible through REST API
Disadvantages
- Requires self-hosting
- No traditional plugin system
- No real-time collaboration features
- No native mobile apps (web is fully responsive)
- Backup and maintenance are user responsibility
- Permission management can become complex for large organizations
Practical Examples
1. BookStack Setup with Docker
version: '3'
services:
bookstack:
image: linuxserver/bookstack
container_name: bookstack
environment:
- PUID=1000
- PGID=1000
- DB_HOST=bookstack_db
- DB_USER=bookstack
- DB_PASS=password
- DB_DATABASE=bookstackapp
- APP_URL=https://docs.example.com
volumes:
- ./bookstack_data:/config
ports:
- 6875:80
restart: unless-stopped
depends_on:
- bookstack_db
bookstack_db:
image: mariadb
container_name: bookstack_db
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=bookstackapp
- MYSQL_USER=bookstack
- MYSQL_PASSWORD=password
volumes:
- ./bookstack_db_data:/var/lib/mysql
restart: unless-stopped
2. API Authentication and Token Generation (PHP)
<?php
// BookStack API Client
class BookStackClient {
private $baseUrl;
private $tokenId;
private $tokenSecret;
public function __construct($baseUrl, $tokenId, $tokenSecret) {
$this->baseUrl = rtrim($baseUrl, '/');
$this->tokenId = $tokenId;
$this->tokenSecret = $tokenSecret;
}
private function getAuthHeader() {
return 'Token ' . $this->tokenId . ':' . $this->tokenSecret;
}
public function request($method, $endpoint, $data = null) {
$ch = curl_init($this->baseUrl . '/api' . $endpoint);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: ' . $this->getAuthHeader(),
'Content-Type: application/json'
]);
if ($data !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
// Usage example
$client = new BookStackClient(
'https://docs.example.com',
'your-token-id',
'your-token-secret'
);
// Get all books
$books = $client->request('GET', '/books');
3. Automated Page Creation (Python)
import requests
import json
from datetime import datetime
class BookStackAPI:
def __init__(self, base_url, token_id, token_secret):
self.base_url = base_url.rstrip('/')
self.headers = {
'Authorization': f'Token {token_id}:{token_secret}',
'Content-Type': 'application/json'
}
def create_page(self, book_id, chapter_id, name, content, tags=None):
"""Create a new page"""
data = {
'book_id': book_id,
'chapter_id': chapter_id,
'name': name,
'html': content
}
if tags:
data['tags'] = tags
response = requests.post(
f'{self.base_url}/api/pages',
headers=self.headers,
json=data
)
return response.json()
def create_documentation_structure(self):
"""Automatically create project documentation structure"""
# Create book
book_data = {
'name': 'Project Documentation',
'description': 'Technical documentation for the development project'
}
book = requests.post(
f'{self.base_url}/api/books',
headers=self.headers,
json=book_data
).json()
# Create chapters
chapters = [
{'name': 'Architecture', 'description': 'System design'},
{'name': 'API Specification', 'description': 'API endpoints'},
{'name': 'Developer Guide', 'description': 'Guide for developers'}
]
for chapter_data in chapters:
chapter_data['book_id'] = book['id']
requests.post(
f'{self.base_url}/api/chapters',
headers=self.headers,
json=chapter_data
)
return book
# Usage example
api = BookStackAPI(
'https://docs.example.com',
'your-token-id',
'your-token-secret'
)
# Create documentation structure
book = api.create_documentation_structure()
print(f"Created book: {book['name']} (ID: {book['id']})")
4. Custom Theme Settings (CSS)
/* BookStack Custom Theme - Add via settings */
:root {
--color-primary: #2c3e50;
--color-primary-light: #34495e;
--color-link: #3498db;
--color-page: #ffffff;
--color-page-draft: #fff5d9;
}
/* Dark mode support */
.dark-mode {
--color-page: #1a1a1a;
--color-text: #e0e0e0;
--color-page-draft: #3a3a2a;
}
/* Custom logo style */
.logo-image {
max-height: 50px;
margin-right: 10px;
}
/* Sidebar customization */
.book-tree .sidebar-page-list {
border-left: 3px solid var(--color-primary);
padding-left: 10px;
}
/* Improved code block styling */
pre code {
background-color: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
font-family: 'Fira Code', monospace;
}
5. Backup Script (Bash)
#!/bin/bash
# BookStack Automated Backup Script
# Configuration
BACKUP_DIR="/backup/bookstack"
DOCKER_CONTAINER="bookstack"
DB_CONTAINER="bookstack_db"
DATE=$(date +%Y%m%d_%H%M%S)
# Create backup directory
mkdir -p "$BACKUP_DIR/$DATE"
# Backup database
echo "Backing up database..."
docker exec $DB_CONTAINER mysqldump -u bookstack -ppassword bookstackapp > "$BACKUP_DIR/$DATE/database.sql"
# Backup uploaded files
echo "Backing up uploaded files..."
docker cp $DOCKER_CONTAINER:/config/uploads "$BACKUP_DIR/$DATE/uploads"
# Backup configuration
echo "Backing up configuration..."
docker cp $DOCKER_CONTAINER:/config/.env "$BACKUP_DIR/$DATE/.env"
# Compress backup
echo "Compressing backup..."
cd "$BACKUP_DIR"
tar -czf "bookstack_backup_$DATE.tar.gz" "$DATE"
rm -rf "$DATE"
# Remove old backups (older than 30 days)
find "$BACKUP_DIR" -name "bookstack_backup_*.tar.gz" -mtime +30 -delete
echo "Backup complete: bookstack_backup_$DATE.tar.gz"