BookStack
コラボレーションツール
BookStack
概要
BookStackは、情報を整理・保存するためのシンプルで使いやすいセルフホスト型プラットフォームです。MIT ライセンスの完全に無料でオープンソースのソフトウェアで、書籍の概念に基づいて設計されています。直感的な階層構造により、ドキュメントの作成と管理が簡単に行え、チームや組織の知識共有に最適です。
詳細
BookStackは、本棚(Shelves)、本(Books)、章(Chapters)、ページ(Pages)という4つの階層レベルで情報を整理します。WYSIWYGエディタとMarkdownエディタの両方を提供し、diagrams.net統合による図表作成機能も内蔵しています。完全に検索可能なコンテンツ、多言語サポート、柔軟な権限管理システムを備え、REST APIによるプログラマティックな操作も可能です。PHPとLaravelフレームワークで構築され、MySQLを使用してデータを保存します。
主な機能
- 階層的な整理: 本棚、本、章、ページの4レベル構造
- デュアルエディタ: WYSIWYGとMarkdownエディタ(ライブプレビュー付き)
- 図表作成: diagrams.net統合による直接的な図表作成
- 強力な検索: 本レベルまたは全体での完全テキスト検索
- バージョン管理: ページの履歴とリビジョン追跡
- 権限管理: 役割ベースのアクセス制御(閲覧者、編集者、管理者)
- 認証オプション: メール/パスワード、ソーシャルログイン、SAML2、LDAP対応
- カスタマイズ: ロゴ、名前、テーマ(ライト/ダーク)の変更可能
API概要
REST API基本構造
GET https://example.com/api/books
Authorization: Token {id}:{secret}
Content-Type: application/json
主要エンドポイント
# 本の一覧取得
GET /api/books
# 新しいページ作成
POST /api/pages
{
"book_id": 1,
"name": "新しいページ",
"html": "<p>ページの内容</p>"
}
# ページの更新
PUT /api/pages/{id}
{
"name": "更新されたページ",
"html": "<p>更新された内容</p>"
}
メリット・デメリット
メリット
- 完全無料でオープンソース(MITライセンス)
- シンプルで直感的なユーザーインターフェース
- セルフホスト型でデータを完全に管理
- 軽量で高速($5のVPSでも動作可能)
- 多言語対応(日本語を含む多数の言語)
- 柔軟な認証オプション
- REST APIによる拡張性
デメリット
- セルフホスティングが必要
- 従来のプラグインシステムがない
- リアルタイムコラボレーション機能がない
- モバイルアプリがない(Webは完全レスポンシブ)
- バックアップとメンテナンスは自己責任
- 大規模な組織では権限管理が複雑になる可能性
実践的な例
1. DockerでのBookStackセットアップ
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認証とトークン生成(PHP)
<?php
// BookStack API クライアント
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);
}
}
// 使用例
$client = new BookStackClient(
'https://docs.example.com',
'your-token-id',
'your-token-secret'
);
// すべての本を取得
$books = $client->request('GET', '/books');
3. ページの自動作成(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):
"""新しいページを作成"""
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):
"""プロジェクトドキュメント構造を自動作成"""
# 本を作成
book_data = {
'name': 'プロジェクトドキュメント',
'description': '開発プロジェクトの技術文書'
}
book = requests.post(
f'{self.base_url}/api/books',
headers=self.headers,
json=book_data
).json()
# 章を作成
chapters = [
{'name': 'アーキテクチャ', 'description': 'システム設計'},
{'name': 'API仕様', 'description': 'APIエンドポイント'},
{'name': '開発ガイド', 'description': '開発者向けガイド'}
]
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
# 使用例
api = BookStackAPI(
'https://docs.example.com',
'your-token-id',
'your-token-secret'
)
# ドキュメント構造を作成
book = api.create_documentation_structure()
print(f"Created book: {book['name']} (ID: {book['id']})")
4. カスタムテーマ設定(CSS)
/* BookStackカスタムテーマ - 設定画面から追加 */
:root {
--color-primary: #2c3e50;
--color-primary-light: #34495e;
--color-link: #3498db;
--color-page: #ffffff;
--color-page-draft: #fff5d9;
}
/* ダークモード対応 */
.dark-mode {
--color-page: #1a1a1a;
--color-text: #e0e0e0;
--color-page-draft: #3a3a2a;
}
/* カスタムロゴスタイル */
.logo-image {
max-height: 50px;
margin-right: 10px;
}
/* サイドバーのカスタマイズ */
.book-tree .sidebar-page-list {
border-left: 3px solid var(--color-primary);
padding-left: 10px;
}
/* コードブロックのスタイル改善 */
pre code {
background-color: #2d2d2d;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
font-family: 'Fira Code', monospace;
}
5. バックアップスクリプト(Bash)
#!/bin/bash
# BookStack自動バックアップスクリプト
# 設定
BACKUP_DIR="/backup/bookstack"
DOCKER_CONTAINER="bookstack"
DB_CONTAINER="bookstack_db"
DATE=$(date +%Y%m%d_%H%M%S)
# バックアップディレクトリ作成
mkdir -p "$BACKUP_DIR/$DATE"
# データベースのバックアップ
echo "データベースをバックアップ中..."
docker exec $DB_CONTAINER mysqldump -u bookstack -ppassword bookstackapp > "$BACKUP_DIR/$DATE/database.sql"
# アップロードファイルのバックアップ
echo "アップロードファイルをバックアップ中..."
docker cp $DOCKER_CONTAINER:/config/uploads "$BACKUP_DIR/$DATE/uploads"
# 設定ファイルのバックアップ
echo "設定ファイルをバックアップ中..."
docker cp $DOCKER_CONTAINER:/config/.env "$BACKUP_DIR/$DATE/.env"
# 圧縮
echo "バックアップを圧縮中..."
cd "$BACKUP_DIR"
tar -czf "bookstack_backup_$DATE.tar.gz" "$DATE"
rm -rf "$DATE"
# 古いバックアップを削除(30日以上)
find "$BACKUP_DIR" -name "bookstack_backup_*.tar.gz" -mtime +30 -delete
echo "バックアップ完了: bookstack_backup_$DATE.tar.gz"