最稳妥省事的部署方式是Docker Compose:5分钟内可访问首页,避免手动部署PHP/Nginx/MySQL的兼容性、权限及APP_KEY生成等问题,关键需正确配置APP_URL、DB_HOST、PUID/PGID等环境变量并确保镜像拉取正常。

BookStack 在 Linux 上最稳妥、最省事的部署方式是 Docker Compose,不是手动编译 PHP + Nginx + MySQL。手动部署容易卡在 php-mbstring、php-xml、composer install 权限或 APP_KEY 生成失败上,尤其在 Rocky / CentOS 8+ 或 Ubuntu 22.04+ 默认禁用 php-fpm socket 权限时。
直接用 docker compose 启一个容器,5 分钟内可访问首页,后续再考虑反向代理或远程穿透。
确认系统已装好 Docker 和 docker-compose
执行 docker --version 和 docker compose version(注意是 compose,不是旧版 docker-compose)。Ubuntu 22.04+ 或通过官方脚本安装的 Docker(如 curl ... | bash -s docker --mirror Aliyun)已自带 docker compose 插件,无需单独装 docker-compose v1。
如果报错 Command "compose" not available,说明插件未启用,运行:
sudo apt install docker-compose-plugin
常见坑:
-
docker服务没启动:执行sudo systemctl start docker并sudo systemctl enable docker - 当前用户不在
docker组:执行sudo usermod -aG docker $USER,然后重新登录终端 - 镜像拉取超时:编辑
/etc/docker/daemon.json加入国内镜像源,例如"https://docker.m.daocloud.io",再sudo systemctl restart docker
docker-compose.yml 必须配对的环境变量
ghcr.io/linuxserver/bookstack:latest 镜像不接受空 DB_HOST 或默认 APP_URL,漏写会导致容器反复重启,日志里只显示 Database connection failed 或 APP_KEY required。
关键字段必须显式声明(不能靠镜像默认值):
-
APP_URL:填你实际访问的地址,比如http://192.168.1.100:8282或https://docs.example.com;本地测试可先写http://localhost:8282,但后续配 Nginx 反代时必须同步改掉 -
DB_HOST:必须和depends_on下的服务名一致,这里是db,不是localhost或127.0.0.1 -
PUID/PGID:建议设成当前用户 ID(id -u/id -g),否则/config卷内文件权限错乱,升级或备份时会失败 -
DB_PASS和MYSQL_PASSWORD必须严格一致,大小写敏感
示例片段(保存为 docker-compose.yml):
services:
bookstack:
image: ghcr.io/linuxserver/bookstack:latest
container_name: bookstack
environment:
- PUID=1000
- PGID=1000
- APP_URL=http://localhost:8282
- DB_HOST=db
- DB_USER=bookstack
- DB_PASS=secret
- DB_DATABASE=bookstack
volumes:
- ./bookstack-data:/config
ports:
- 8282:80
depends_on:
- db
<p>db:
image: mysql:5.7
container_name: bookstack_db
environment:</p>
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=bookstack
- MYSQL_USER=bookstack
- MYSQL_PASSWORD=secret volumes:
- ./mysql-data:/var/lib/mysql
启动后打不开页面?先查这三处
执行 sudo docker compose up -d 后,别急着开浏览器。先验证基础状态:
- 容器是否真在运行:
sudo docker ps | grep bookstack—— 应看到两个 UP 状态容器;若只有db在跑,bookstack闪退,立刻看日志:sudo docker logs bookstack - 端口是否被占:
ss -tuln | grep :8282—— 如果被其他进程占用,改ports为8283:80等可用端口 - 数据库初始化是否完成:
sudo docker exec -it bookstack_db mysql -u bookstack -psecret bookstack -e "SHOW TABLES;"—— 应返回一堆表名(如books、pages);如果报错Access denied,检查MYSQL_PASSWORD和DB_PASS是否完全一致
典型错误日志片段:
-
SQLSTATE[HY000] [1045] Access denied for user 'bookstack'@'172.18.0.3'→ 密码不匹配或DB_HOST写成localhost -
Target class [App\Http\Controllers\PagesController] does not exist→/config卷损坏,删掉./bookstack-data重来(前提没存重要数据) - 浏览器显示
502 Bad Gateway→ 你加了 Nginx 但没配好proxy_pass http://127.0.0.1:8282,或者APP_URL还是http://localhost:8282没改成域名
中文显示异常或 PDF 导出空白?补字体和依赖
LinuxServer 的 bookstack 镜像基于 Alpine,精简掉了中文字体和 calibre 所需的 GUI 依赖。遇到「方块字」「导出 PDF 是空白页」或「目录生成失败」,不是配置问题,是缺包。
解决方案只有两个:
- 临时修复(仅限测试):进容器装字体:
sudo docker exec -it bookstack apk add ttf-dejavu ttf-droid,然后重启容器 - 长期方案:改用自定义 Dockerfile,在镜像构建阶段加入:
RUN apk add --no-cache ttf-dejavu ttf-droid calibre;或者直接在宿主机装好calibre,把ebook-convert路径挂进容器(需额外配置CALIBRE_PATH环境变量)
注意:calibre 在 Alpine 上兼容性差,生产环境建议用 Ubuntu 基础镜像自行构建,或干脆放弃 PDF 导出,专注 Web 协作。
真正容易被忽略的一点:APP_URL 一旦设为 https,所有资源(CSS/JS/图片)都强制走 HTTPS,如果反代层没传 X-Forwarded-Proto 头,页面会加载失败且控制台报混合内容错误——这个比字体问题更隐蔽,也更难排查。











