BookStack 日常运维手册

BookStack v26.09.1 日常运维手册:巡检(健康端点/队列监控/磁盘)、16 个内置维护命令、备份与恢复全流程演练(41 表闭环)、监控告警脚本、升级回滚与 7 类故障排查,全部命令实测附真实回显。

BookStackBookStack2026/10/18

BookStack 日常运维手册

目标:为已上线的 BookStack v26.09.1 实例提供日常运维的完整操作手册——巡检、内容维护、备份恢复、监控告警、升级回滚与故障排查,全部命令均在 v26.09.1 实例上实测并附真实回显;部署与配置背景分别见《BookStack Docker Compose 部署指南》《BookStack v26.09.1 配置参数详解》。

一、环境信息

  • BookStack 版本:v26.09.1(应用框架 Laravel 12.69.3,运行时 PHP 8.5.11)
  • 操作系统:Ubuntu 22.04 LTS
  • 数据库:MariaDB 11.8(满足官方要求的 MariaDB ≥ 10.6 / MySQL ≥ 8.0)
  • 应用根目录:/var/www/bookstack(官方安装布局;下文 artisan 命令均以此为基准)
  • 应用属主:www-data(官方 Ubuntu 安装脚本默认)
  • 备份目录:/backup(本手册约定,生产按实际调整并确保挂载独立磁盘或异地存储)
  • 管理员账号:admin@example.com(演示口令 q1w2e3r4)
  • 数据库账号:bookstack(仅授予 bookstack 库权限);root 仅用于恢复演练与账号维护
  • 站点地址:http://192.168.146.128:8112,健康检查端点 http://192.168.146.128:8112/status

二、前置条件

  1. 已部署并可登录的 BookStack v26.09.x 实例;能以 www-data 身份在应用根目录执行 php artisan。
  2. 数据库客户端可用(mysqldump / mysql 命令行),并掌握 DB_PASSWORD。
  3. 有 /backup 目录(或替代的备份目录),磁盘余量大于当前数据体积的 2 倍以上。
  4. 明确两个"数据事实",是本手册所有备份/恢复动作的对象:
    • 库:一个 MySQL/MariaDB 库(默认 41 张表,实测见 5.3 节),承载全部内容、用户、权限与设置;
    • 文件:public/uploads(公开图片)与 storage/uploads(私有附件/图库文件)两个目录,外加 .env 配置文件(含 APP_KEY,必须随备份保存)。

三、日常巡检

巡检目标:5 分钟内确认服务活着、数据库连得上、队列没积压、磁盘没满。以下命令均可纳入每日 cron 脚本(6.1 节)。

3.1 健康检查端点

/status 是内置健康检查,返回三大子系统状态;任何子系统异常时响应码 ≥ 400:

curl -s http://localhost:8112/status && echo
curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://localhost:8112/status

实测回显:

{"database":true,"cache":true,"session":true}
HTTP 200

巡检脚本按 JSON 三个布尔值判断:全 true 且 HTTP 200 即健康;脚本化判断示例见 6.1 节。

3.2 环境总览与版本核对

cd /var/www/bookstack && sudo -u www-data php artisan about | head -12

实测回显(重点看 Laravel/PHP 版本、Debug Mode 是否 OFF):


  Environment ................................................................
  Application Name ................................................... Laravel
  Laravel Version .................................................... 12.69.3
  PHP Version ......................................................... 8.5.11
  Composer Version .................................................... 2.10.3
  Environment ..................................................... production
  Debug Mode ............................................................. OFF
  URL ................................................... 192.168.146.128:8112
  Maintenance Mode ....................................................... OFF
  Timezone ............................................................... UTC

3.3 数据库连通性

cd /var/www/bookstack && sudo -u www-data php artisan tinker --execute='echo "db_connected=".(DB::select("select 1") ? "yes" : "no")." users=".DB::table("users")->count().PHP_EOL;'

实测回显:

db_connected=yes users=3

3.4 队列积压检查

启用异步队列(QUEUE_CONNECTION=database)后,积压会拖慢邮件与 Webhook。Laravel 内置监控命令:

cd /var/www/bookstack && sudo -u www-data php artisan queue:monitor database --max=500
sudo -u www-data php artisan queue:failed

实测回显(空队列健康态):


  Queue name ................................................... Size / Status
  [database] database ................................................. [0] OK
  Pending jobs ............................................................. 0
  Delayed jobs ............................................................. 0
  Reserved jobs ............................................................ 0
  Oldest pending job ..................................................... N/A

   INFO  No failed jobs found.

3.5 磁盘占用

应用数据体积随时间增长,巡检时盯住两个上传数据目录与日志体量:

cd /var/www/bookstack/public && sudo du -sh uploads
cd /var/www/bookstack/storage/uploads && sudo du -sh files images
sudo find /var/www/bookstack/storage/logs -name '*.log' -size +50M

实测回显(实例刚初始化、尚无上传内容,目录各占 4.0K 属正常):

4.0K    uploads
4.0K    files
4.0K    images

第三条无输出即无超 50M 的日志文件(本实测无输出)。

💡 说明: BookStack 的上传文件按年份月份子目录落盘(public/uploads/2026-10/ 风格),增长平滑可预期;巡检把 3.1~3.5 的输出留存或写入脚本(6.1 节)即可对比趋势。

四、内容维护命令

BookStack 内置 16 个 bookstack: 运维命令(php artisan list bookstack 可随时查看),覆盖内容重建、清理与账号维护:

命令用途危险级别
bookstack:regenerate-search重建全文搜索索引无损,随时可跑
bookstack:regenerate-permissions重建全部权限关系无损,随时可跑
bookstack:regenerate-references重建跨条目引用索引无损,随时可跑
bookstack:cleanup-images清理无引用图片(默认 dry-run)加 -f 才真删
bookstack:clear-revisions清除页面修订历史不可逆,先备份
bookstack:clear-activity清除用户活动(审计)日志不可逆,先备份
bookstack:clear-views清除全部浏览计数不可逆
bookstack:db-utf8mb4输出升级到 UTF8mb4 的 SQL仅输出不改库
bookstack:copy-shelf-permissions把书架权限复制到子书覆盖子书权限
bookstack:create-admin新建管理员无损
bookstack:delete-users删除非管理员/非系统用户不可逆
bookstack:reset-mfa重置指定用户的 MFA影响该用户
bookstack:refresh-avatar重新拉取指定用户头像无损
bookstack:update-url全库替换历史 URL改库,先备份
bookstack:assign-sort-rule给存量内容应用排序规则改动排序
bookstack:install-module安装主题模块无损

4.1 索引重建三件套(无损,排障首选)

搜索结果异常、权限显示错乱、引用链接失效时,按需执行(全部幂等,实测回显):

cd /var/www/bookstack && sudo -u www-data php artisan bookstack:regenerate-search
Search index regenerated!
sudo -u www-data php artisan bookstack:regenerate-permissions
Permissions regenerated
sudo -u www-data php artisan bookstack:regenerate-references
References have been regenerated

4.2 图片清理(默认演练模式)

清理已无页面引用的上传图片,默认 dry-run 只报告不删除,确认后再加 --force:

cd /var/www/bookstack && sudo -u www-data php artisan bookstack:cleanup-images --no-interaction

实测回显(当前无孤儿图片):

Dry run, no images have been deleted
0 image(s) found that would have been deleted
Run with -f or --force to perform deletions

4.3 修订与活动日志清理(不可逆,先备份)

页面修订历史会无限增长(默认上限 REVISION_LIMIT=100 每页),确有瘦身需求时先执行第五章备份,再清理:

sudo -u www-data php artisan bookstack:clear-revisions --all
sudo -u www-data php artisan bookstack:clear-activity --all

⚠️ 注意:这两条命令删除的数据无法恢复(修订历史=回滚能力,活动日志=审计追溯)。生产环境建议保留默认策略,仅在与合规团队确认后执行;清理前把备份文件留存到 /backup。

五、备份与恢复

官方备份文档(bookstackapp.com/docs/admin/backup-restore/)要求的备份对象为:数据库 + 上传文件 + .env。本节给出可脚本化的完整方案并做恢复演练。

5.1 备份清单与目录布局

/backup/
├── bookstack-db-2026-10-18.sql      # 数据库全量导出
├── bookstack-files-2026-10-18.tar.gz # public/uploads + storage/uploads
└── bookstack-env-2026-10-18.tar.gz   # .env(含 APP_KEY,必须妥善保管)

三件缺一不可:只有库没有文件 → 图片/附件全丢;没有 .env → APP_KEY 丢失导致加密数据不可解密。

5.2 数据库备份

mysqldump -u bookstack -p bookstack > /backup/bookstack-db-$(date +%F).sql
ls -lh /backup/bookstack-db-2026-10-18.sql

实测回显(全新实例 58K,随内容增长):

-rw-r--r-- 1 root root 58K Oct 18 21:39 /backup/bookstack-db-2026-10-18.sql

确认导出完整(41 张表):

grep -c 'CREATE TABLE' /backup/bookstack-db-2026-10-18.sql

实测回显:

41

5.3 文件与配置备份

cd /var/www/bookstack
tar czf /backup/bookstack-files-$(date +%F).tar.gz public/uploads storage/uploads
tar czf /backup/bookstack-env-$(date +%F).tar.gz .env
ls -lh /backup/bookstack-files-2026-10-18.tar.gz /backup/bookstack-env-2026-10-18.tar.gz

实测回显:

-rw-r--r-- 1 root root 1.1K Oct 18 21:39 /backup/bookstack-env-2026-10-18.tar.gz
-rw-r--r-- 1 root root  130 Oct 18 21:39 /backup/bookstack-files-2026-10-18.tar.gz

💡 说明:实测环境为全新实例,两个目录内容极少所以 tar 包很小;正常使用中的实例以 3.5 节 du 统计的实际体积为准评估备份空间。

5.4 恢复演练(全流程实测)

恢复分两步:先库后文件。实测要点:导入必须用数据库 root(或对目标库有全部权限的账号)——本节演练时用业务账号 bookstack 导入新库被拒绝(ERROR 1044 (42000): Access denied for user 'bookstack'@'%' to database 'bookstack_restore'),因为业务账号默认只授权了本库,这正是演练的价值。

# 1. 建一个空库(演练用,生产恢复即目标库)
mysql -u root -p -e "CREATE DATABASE bookstack_restore CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# 2. 导入备份(用 root 或有权限的账号)
mysql -u root -p bookstack_restore < /backup/bookstack-db-2026-10-18.sql

# 3. 核对表数量与用户数
mysql -u root -p -e "SELECT COUNT(*) AS tables_in_restore FROM information_schema.tables WHERE table_schema='bookstack_restore'; SELECT COUNT(*) AS users_in_restore FROM bookstack_restore.users;"

# 4. 演练库用完即删
mysql -u root -p -e "DROP DATABASE bookstack_restore;"

实测回显(第 3 步,41 张表与 3 个用户与源库一致;第 4 步执行无报错):

tables_in_restore
41
users_in_restore
3

💡 技术拓展:完整恢复到全新服务器 = 恢复演练的两步 + 把 bookstack-files 包解压到对应目录 + 把 .env 解压回应用根目录并核对 APP_KEY 与 DB_PASSWORD 与新环境一致。建议每季度做一次到演练机的全量恢复,验证备份可用性。

六、监控与告警

6.1 巡检脚本与 cron

把第三章巡检项串成一个脚本 /opt/scripts/bookstack-health.sh,任一异常即退出码非 0(便于接入现有监控):

#!/bin/bash
# BookStack 健康巡检:健康端点 + 队列 + 数据库
set -e
BODY=$(curl -sf --max-time 10 http://localhost:8112/status)
echo "$BODY" | grep -q '"database":true' || { echo "FAIL: database subsystem"; exit 1; }
cd /var/www/bookstack
sudo -u www-data php artisan tinker --execute='echo DB::select("select 1") ? "db=yes" : "db=no";' | grep -q 'db=yes'
sudo -u www-data php artisan queue:monitor database --max=500 | grep -q ' OK ' || { echo "FAIL: queue backlog"; exit 1; }
echo "ALL OK: $(date '+%F %T') $BODY"

加入系统 cron(每 10 分钟一次):

sudo chmod +x /opt/scripts/bookstack-health.sh
(sudo crontab -l; echo '*/10 * * * * /opt/scripts/bookstack-health.sh >> /var/log/bookstack-health.log 2>&1') | sudo crontab -

💡 说明:脚本的三段检查分别对应 3.1/3.3/3.4 节的实测行为(健康 JSON、select 1 连通、队列 OK 状态),异常时 exit 1 可直接对接 Zabbix/Prometheus blackbox 类告警或企业微信/邮件通知脚本。

6.2 日志巡检

BookStack 应用日志在 storage/logs/laravel.log(单文件滚动),异常排障第一现场。巡检关注当日 ERROR:

sudo grep "$(date +%F)" /var/www/bookstack/storage/logs/laravel.log | grep -c ERROR

实测回显(本实例存在离线环境拉取头像失败的记录,属可预期噪声,见 9.2 节):

3

日志样本(本实例真实条目,离线环境拉取 Gravatar 失败):

[2026-10-18 13:12:04] production.ERROR: Failed to save user avatar image {"exception":"[object] (BookStack\\Exceptions\\HttpFetchException(code: 0): Cannot get image from https://w

失败登录审计(若配置了 LOG_FAILED_LOGIN_MESSAGE)进 Web 服务器错误日志,巡检可直接 grep 关键字(实测样本见《BookStack v26.09.1 配置参数详解》5.8 节)。

七、升级与回滚

7.1 升级前检查

# 1. 核对当前版本(官方升级文档第一步)
cd /var/www/bookstack && sudo -u www-data php artisan about | grep 'Laravel Version'
# 2. 迁移状态清单(升级后逐条变为 Ran)
sudo -u www-data php artisan migrate:status | tail -3

实测回显:

  Laravel Version .................................................... 12.69.3
  2026_04_19_141616_add_revision_view_all_permission ................. [1] Ran
  2026_07_27_201402_update_users_external_auth_id_collation .......... [1] Ran
# 3. 完整备份(第五章三件套)
mysqldump -u bookstack -p bookstack > /backup/bookstack-db-pre-upgrade.sql

7.2 官方升级流程

官方 Updates 文档(bookstackapp.com/docs/admin/updates/)对 git 方式部署的升级三步(换新版本号示例:v26.09.1 → 下一版本):

cd /var/www/bookstack
sudo -u www-data git fetch --tags && sudo -u www-data git checkout v26.10.0
sudo -u www-data composer install --no-dev
sudo -u www-data php artisan migrate --force

实测证据(当前已是最新版,重复执行 migrate 的幂等回显——升级最后一步无 schema 变更时的标准输出):


   INFO  Nothing to migrate.

⚠️ 注意:migrate 在生产环境必须带 --force(不带会交互确认,实测未带时输出 WARN Command cancelled.);升级期间站点不可写属预期(官方不承诺升级窗口内可用性),低峰执行。跨多个大版本升级先逐版本阅读官方更新说明。

7.3 回滚方案

升级失败的标准回滚路径(依赖 7.1 步的 pre-upgrade 备份):

# 1. 代码回退到旧版本标签
cd /var/www/bookstack && sudo -u www-data git checkout v26.09.1
sudo -u www-data composer install --no-dev

# 2. 数据库回滚:导入升级前备份
mysql -u root -p -e "DROP DATABASE bookstack; CREATE DATABASE bookstack CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u root -p bookstack < /backup/bookstack-db-pre-upgrade.sql

# 3. 文件不动(上传文件向前兼容),核对 /status 与登录
curl -s http://localhost:8112/status

💡 说明:数据库 migration 官方没有自动降级命令,因此"升级前全量备份"是回滚的唯一前提,务必先备份再升级。

八、扩容与参数调整

需求操作关联配置
上传限额提高三层同步:PHP upload_max_filesize/post_max_size → Web 服务器 client_max_body_size → .env FILE_UPLOAD_SIZE_LIMIT,改后重载 PHP 与 Web 服务FILE_UPLOAD_SIZE_LIMIT=100
邮件/Webhook 转异步QUEUE_CONNECTION 改 database(实测队列日志出现 Async Action Queue 工作进程),并确认 3.4 节巡检纳入 cronQUEUE_CONNECTION=database
多实例共享状态SESSION_DRIVER 与 CACHE_DRIVER 改 database 或 redis(实测 database 驱动会话/缓存落库)SESSION_DRIVER=database
界面时区APP_DISPLAY_TIMEZONE=Asia/Shanghai(存储保持 UTC)APP_DISPLAY_TIMEZONE
每页修订上限REVISION_LIMIT(默认 100,实测可调)REVISION_LIMIT=100
数据盘扩容新磁盘挂载 → 停服务(systemctl stop nginx php*-fpm 类)→ 迁移 public/uploads 与 storage/uploads → 软链或改挂载 → 起服务 → 3.1 节健康检查—

💡 说明:参数级调整(各 .env 键的默认值、生效机制与实测证据)全集见《BookStack v26.09.1 配置参数详解》,本表只列运维触发场景。配置改动后务必检查 config 缓存状态(php artisan about 的 Config 行),CACHED 时执行 php artisan config:clear。

九、故障排查手册

9.1 页面 500 / 空白

第一现场永远是应用日志:

sudo tail -n 30 /var/www/bookstack/storage/logs/laravel.log

按异常类型分流:数据库类异常(Connection refused/Access denied)→ 9.3 节;权限类(Permission denied 写 storage)→ 核对应用目录属主为 www-data;其他异常记录堆栈后对照 4.1 节三件套重建索引与权限。

9.2 头像加载失败 / 外部服务超时

实测样本(本实例真实日志条目):

[2026-10-18 13:12:04] production.ERROR: Failed to save user avatar image {"exception":"[object] (BookStack\\Exceptions\\HttpFetchException(code: 0): Cannot get image from https://w

原因:创建用户时默认尝试拉取 Gravatar 头像,服务器无外网(或网络受限)时记录此错误。不影响登录与核心功能。处置:内网环境在 .env 设 DISABLE_EXTERNAL_SERVICES=true(关闭 Gravatar/Draw.io 等外链服务),或用 php artisan bookstack:refresh-avatar 在有网时补拉。

9.3 数据库连接失败

cd /var/www/bookstack && sudo -u www-data php artisan tinker --execute='echo (DB::select("select 1") ? "db=yes" : "db=no").PHP_EOL;'

实测回显(正常态):

db=yes

异常时按序核对:数据库进程活着(systemctl status mariadb)→ .env 六个 DB_* 值与实际一致 → 手工连库验证(mysql -u bookstack -p bookstack -e "select 1")→ 防火墙 3306 出入站。

9.4 搜索结果缺失或过期

重建搜索索引(无损,实测回显):

sudo -u www-data php artisan bookstack:regenerate-search
Search index regenerated!

9.5 权限显示错乱 / 改权限不生效

重建权限关系(无损,实测回显):

sudo -u www-data php artisan bookstack:regenerate-permissions
Permissions regenerated

书架级权限改动未传导到子书时用 bookstack:copy-shelf-permissions(会覆盖子书权限,先确认)。

9.6 队列积压 / 邮件不发送

sudo -u www-data php artisan queue:monitor database --max=500
sudo -u www-data php artisan queue:failed

实测回显(健康态见 3.4 节)。积压时先看进程是否存活(QUEUE_CONNECTION=database 需要队列工作进程持续运行,部署形态不同检查方式不同:systemd 单元状态或 ps aux | grep queue:work);有失败任务时 php artisan queue:retry all 重放,反复失败的按任务报错修复根因(最常见是 SMTP 凭据)。

9.7 管理员口令遗忘

新建一个管理员接管(实测回显):

sudo -u www-data php artisan bookstack:create-admin --email=root@example.com --name=root --password=q1w2e3r4
Admin account with email "root@example.com" successfully created!

登录后修复或删除旧账号;目标用户开启了 MFA 无法进站时先 php artisan bookstack:reset-mfa <邮箱>。

十、常见问题

Q1:巡检脚本哪些项必须进 cron? 最小集:6.1 节健康脚本(含 /status、数据库连通、队列)每 10 分钟;数据库备份按 RPO 决定频率(日更库建议每日凌晨);日志 ERROR 计数可并入健康脚本。BookStack 自身的计划任务(回收站过期清理等)由系统 cron 每分钟触发 php artisan schedule:run(官方标准配置:* * * * * www-data cd /var/www/bookstack && php artisan schedule:run),二者职责不同,都要有。

Q2:备份文件放本机同一块盘安全吗? 不安全。磁盘故障时库和备份一起丢。标准做法:备份脚本追加异地推送(rsync 到备份服务器或对象存储),并每季度按 5.4 节做一次恢复演练验证可用。

Q3:.env 里的 APP_KEY 要不要单独加密保管? 要。APP_KEY 丢失=加密数据不可解密(密码重置、MFA 相关功能失效)。备份 .env 的介质要控制访问权限(chmod 600、加密存储),与库备份同等对待。

Q4:clear-revisions 清掉的历史还能找回吗? 不能,删库级操作。它清的是 page_revisions 表数据,除非清理前有库备份。正确姿势:平时控制体积用 REVISION_LIMIT(每页保留条数上限,超限自动淘汰最旧),只在确要瘦身且已备份时才手动清。

Q5:升级后页面样式错乱? 浏览器缓存与配置缓存的组合问题:php artisan config:clear + php artisan view:clear,浏览器强刷(Ctrl+Shift+R);仍错乱时确认代码确实 checkout 到了目标版本标签(git describe --tags)。

Q6:如何确认升级成功? 四件核对:php artisan about 版本行是新版本号;php artisan migrate:status 全部 Ran;/status 健康检查 200;抽一页内容能正常打开、编辑并保存。7.1 节命令即这套核对的可执行版本。

十一、参考链接

  1. BookStack 官方备份与恢复文档:https://www.bookstackapp.com/docs/admin/backup-restore/
  2. BookStack 官方升级文档:https://www.bookstackapp.com/docs/admin/updates/
  3. BookStack 官方命令行工具文档:https://www.bookstackapp.com/docs/admin/commands/
  4. BookStack 官方文档站(运维各页入口):https://www.bookstackapp.com/docs/
  5. BookStack v26.09.1 Release(版本核实):https://github.com/BookStackApp/BookStack/releases
  6. 《BookStack Docker Compose 部署指南》(本专栏部署篇)
  7. 《BookStack v26.09.1 配置参数详解》(本专栏配置篇)