最稳方案是用 docker 部署 bookstack,需正确配置 app_url(实际访问地址,不可带斜杠)、db_host(容器服务名 db,非 localhost)、puid/pgid(宿主机用户 id);mysql 8.0 需设 mysql_default_authentication_plugin=mysql_native_password;中文 pdf/截图乱码须挂载中文字体并设 tz=asia/shanghai;app_url 修改后需同步数据库 settings 表或重置 mysql-data。

直接用 Docker 部署最稳,手动编译 PHP + Nginx + MySQL 容易卡在 php-fpm 权限、APP_URL 配置错、mysql:5.7 字符集不兼容等细节上,尤其在 Rocky / CentOS 9+ 或 Ubuntu 22.04+ 上,PHP 8.1+ 和默认 MySQL 8.0 的 caching_sha2_password 认证插件会导致连接失败。
docker-compose 启动 BookStack 必须改的三个 environment 值
官方 ghcr.io/linuxserver/bookstack 镜像虽省事,但默认 APP_URL=http://localhost:8282 会直接导致登录后跳转 404、图片加载失败、API 请求跨域被拒——这不是 Bug,是 Laravel 对请求来源的强制校验。
-
APP_URL必须设为你的实际访问地址,比如反向代理后是https://docs.example.com,就填这个,不能带尾部斜杠 -
DB_HOST在 compose 中是服务名db,不是127.0.0.1或localhost(容器内 localhost 指自己) -
PUID/PGID建议设成宿主机当前用户 ID(运行id -u和id -g查),否则./bookstack-data目录可能因权限不足无法写入附件或日志
MySQL 8.0 容器启动失败或 BookStack 连不上数据库
LinuxServer 的 BookStack 镜像默认适配 mysql:5.7,若你换用 mysql:8.0 或 mysql:8.4,大概率报错:SQLSTATE[HY000] [2054] Server sent charset unknown to the client 或直接拒绝连接。
PyCharm 2026.2.0.1 Linux版提供 JetBrains 官方 2026.2.0.1 版本安装包,适合需要指定 PyCharm 版本进行 Python 项目开发、运行和调试的用户。
- 根本原因是 MySQL 8.0 默认启用
caching_sha2_password,而 BookStack 所用的 PDO MySQL 驱动(PHP 8.0+)未显式指定认证插件 - 解决方法:在
db服务 environment 中加一行MYSQL_DEFAULT_AUTHENTICATION_PLUGIN=mysql_native_password - 或者退回到已验证兼容的
mysql:5.7(推荐,避免额外调试) - 别碰
character_set_server=utf8mb4这类参数——镜像内部已设好,乱加反而触发初始化失败
中文导出 PDF 乱码、截图无汉字、验证码不显示
这三类问题同源:容器内缺中文字体 + Puppeteer 渲染环境未初始化。LinuxServer 的 BookStack 镜像不自带中文字体,calibre 和 puppeteer 都依赖系统级字体文件。
- 临时验证:进容器执行
fc-list :lang=zh,若无输出,说明没中文字体 - 修复方式:挂载宿主机中文字体目录,比如 Ubuntu 上有
/usr/share/fonts/truetype/wqy/,就在bookstack服务下加 volume:- /usr/share/fonts/truetype/wqy:/usr/share/fonts/truetype/wqy:ro - 同时补一条环境变量:
- TZ=Asia/Shanghai(避免时间相关功能异常) - 如果仍乱码,检查是否漏了
fonts-wqy-microhei包——Ubuntu 用sudo apt install fonts-wqy-microhei,Rocky/CentOS 用sudo dnf install wqy-microhei-fonts
APP_URL 改了但登录后还是跳回 localhost
BookStack 会把 APP_URL 写进数据库表 settings 的 app_url 字段,首次启动后该值就固化了。哪怕你改了 docker-compose.yml 并 docker-compose down & up -d,也不会自动同步。
- 必须手动进 MySQL 容器执行:
mysql -u bookstack -psecret bookstack -e "UPDATE settings SET value = 'https://docs.example.com' WHERE name = 'app_url';" - 或者更彻底:删掉
./mysql-data目录(注意备份),让 BookStack 重新初始化数据库 - 顺手清空浏览器缓存或换隐身窗口测试,因为 Laravel 会缓存配置,前端也可能 302 跳转到旧地址
真正麻烦的从来不是拉起容器,而是 APP_URL、数据库认证插件、字体路径这三处隐性耦合点——它们不出错时一切丝滑,一出错就全链路静默失败,日志里还只报“500”或空白页面。










