用Docker Compose部署企业级Wiki(BookStack),避坑指南。

2026-05-13

兄弟们,又是我。最近公司想搞个内部知识库,需求简单:能写文档、能搜、能管权限,别太贵。调研一圈,发现BookStack这个开源项目挺香——纯Web、支持Markdown、还能搞层级结构,关键是社区活跃,GitHub上星星不少。

但说实话,部署BookStack的过程,我踩的坑比上班路上的井盖还多。今天就把这些经验掰开了揉碎了,跟你聊聊怎么用Docker Compose快速部署,顺便把那些容易翻车的地方提前给你打个预防针。

为什么选BookStack?

先说说为啥不选Confluence?贵啊,而且人家是Java堆出来的,内存吃掉一半,小团队根本扛不住。BookStack用PHP,轻量级,500人以下的团队完全够用。界面清爽,支持LDAP、SAML,还能对接钉钉、企业微信,绝对是打工人友好型。

Docker Compose部署,一步到位

我直接写了一个最简单的docker-compose.yml,你拿去就能用:

version: '3'
services:
  bookstack:
    image: lscr.io/linuxserver/bookstack:latest
    container_name: bookstack
    environment:
      - APP_URL=http://yourdomain.com
      - DB_HOST=bookstack_db
      - DB_PORT=3306
      - DB_DATABASE=bookstack
      - DB_USERNAME=bookstack
      - DB_PASSWORD=your_password
    volumes:
      - ./bookstack_data:/config
    ports:
      - 80:80
    restart: unless-stopped
    depends_on:
      - bookstack_db

  bookstack_db:
    image: mysql:8.0
    container_name: bookstack_db
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_DATABASE=bookstack
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=your_password
    volumes:
      - ./mysql_data:/var/lib/mysql
    restart: unless-stopped

是不是看着挺简单?但别急,坑都在后头。

坑一:MySQL版本别选错

BookStack官方说支持MySQL 5.7+,但实测MySQL 8.0有个天坑——默认的认证插件是caching_sha2_password,而BookStack的PHP驱动不一定支持。你会发现数据库连接报错,起不来。

解决办法: 在MySQL的docker-compose.yml环境变量里加这一行:

MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password

或者像我一样,直接用mysql:8.0的镜像,然后在启动后手动执行:

ALTER USER 'bookstack'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';

这就像你家门锁是新款的指纹锁,但BookStack这哥们只认老式钥匙,你得给他配一把。

坑二:端口映射要留个心眼

ports: - 80:80没问题,但如果你本地已经有其他服务占了80端口(比如Nginx、Apache),那你得改。我建议直接用- 8080:80,然后前面挂个Nginx反向代理,统一管理HTTPS。

真实案例: 我同事图省事,直接用80端口,结果跟本机的Jenkins端口冲突,折腾半天才发现。后来我让他把BookStack映射到8888,再用Nginx转发,世界清净了。

坑三:APP_URL必须写对

APP_URL这个环境变量,很多人随便填个http://localhost,然后访问发现图片、CSS都挂了。因为BookStack生成资源链接时依赖这个地址,你填localhost,别人在公司内网用IP访问,自然加载不出来。

正确做法:填你最终对外服务的域名或IP+端口。比如http://192.168.1.100:8080,或者https://wiki.yourcompany.com。如果你以后要改域名,记得重新设置,否则所有链接都废了。

这就像你在名片上印错了公司电话,别人打过来永远是空号。

坑四:文件上传大小限制

BookStack默认上传文件限制是2M,但你的同事肯定要传截图、PDF甚至视频。要改很简单:在docker-compose.yml的environment里加两行:

- MAX_UPLOAD_SIZE=200M
- PHP_UPLOAD_LIMIT=200M

别问我为什么是200M,因为够用,而且PHP本身也有个post_max_size,你最好也调大。否则同事传个高清架构图就报错,你以为是自己姿势不对,其实是坑。

坑五:时区问题

部署完发现文档里的时间全是UTC,比北京时间晚了8小时。解决方法:在environment里加:

- TZ=Asia/Shanghai

或者你在环境变量里写- timezone=Asia/Shanghai(注意BookStack的写法是TZ,不是TIMEZONE)。这个坑我踩了两次,第一次还以为是数据库的问题。

坑六:备份别忘了数据库

有人把BookStack容器跑起来,就觉得万事大吉了。结果某天硬盘坏了,数据全丢。BookStack的数据分两部分:一是上传的附件(存在./bookstack_data里),二是数据库(在./mysql_data里)。

建议你写个定时任务(crontab)每天打包备份这两个目录,再用rsync或者云存储同步到异地。别问我怎么知道的,问就是前公司同事手滑删了生产库,而且还是情人节晚上。

最后,关于升级

BookStack升级挺勤快,但直接用docker pull拉最新版可能会翻车。我建议你先把当前镜像tag锁定,比如lscr.io/linuxserver/bookstack:latest改成lscr.io/linuxserver/bookstack:23.12。想要升级时,先备份,再改tag,重启容器。如果新版本有数据库迁移,它会在启动时自动执行,基本无感。

总结

BookStack确实是个好东西,Docker Compose部署也足够简单。但上面这几个坑,你提前做好预防,就能省下好几杯咖啡的时间。如果你们公司规模再大点,比如千人以上,可能要考虑K8s或者高可用架构——那就不是一篇软文能讲完的了。

不过话说回来,绝大多数中小团队,一个Docker主机加这个配置,完全够用。你只需要把这份docker-compose.yml扔给运维,告诉他“跑一下就行”,然后就能收获全公司的好评。

当然,还有更多企业级方案的详细对比、自动化部署脚本、甚至与LDAP对接的完整配置,我都整理到了 itfangan.com 这个站点上。如果你遇到其他奇奇怪怪的问题,比如PDF导出乱码、搜索不支持中文、或者想对接企微机器人通知,都可以去那里看看,说不定能找到现成的答案。

毕竟,坑不是用来踩的,是用来绕的。共勉。