先说一个我亲测过的场景。前两年我们团队从二十人慢慢涨到六十多人,最明显的变化不是工位不够坐,而是“知识”开始四分五裂:方案讨论散落在聊天记录里,验收标准躺在某个同事的本地文档里,线上出过的问题只存在于老员工的脑子里。新同事入职第一个月,光“找资料”这件事就能吃掉三分之一的时间,问东问西还容易踩旧坑。这不是管理问题,是知识库缺位的问题。
后来我们决定自建一套内部知识库,调研了一圈,最终落地选了 Wiki.js。用了大半年,团队查资料、沉淀方案、交接项目的效率明显改善,我自己也在这个过程中踩了不少坑,积累了一套从部署到日常维护的实操经验。这篇就完整分享一下:为什么选 Wiki.js、怎么设计部署方案、一步步怎么搭起来、内容怎么组织、以及那些官方文档里不太会写的坑。
如果你正被“资料到处飘、经验留不住、新人上手慢”这几个问题困扰,想找一个开源、免费、可自托管的 Wiki 建站工具,或者已经在评估 Wiki.js 但不知道怎么上手,这篇应该能帮你省下不少排查时间。
1. 为什么是 Wiki.js:先聊聊知识库选型
很多团队的第一反应是“随便找个笔记工具就行”,但笔记工具和知识库其实是两类东西。笔记解决的是“个人怎么记”,知识库解决的是“团队怎么查、怎么复用、怎么沉淀”。两者的核心差异在于:内容是组织化、可检索、有权限、可追溯的。所以选型时我重点看了四件事:部署成本、内容格式、权限模型、扩展能力。
1.1 知识孤岛是怎么来的
知识孤岛不是一天形成的。早期团队小,几个人坐在一起,嘴上说一句就等于同步了,文档写不写都无所谓。团队变大之后,信息开始散落到各个“容器”里:微信群、邮件、会议纪要、网盘、个人笔记。这些容器的共同特点是只能存,不能查,或者说查起来成本极高。等到需要某份关键资料时,你根本不知道该问谁、去哪翻,最后只能被迫重新造一遍轮子。
我见过最典型的例子是:一个支付模块的踩坑记录,被某个老开发写在个人博客里,结果另外两个小组分别在不同的项目里重复踩了一遍同样的坑。这不是人的问题,是系统性问题——知识没有集中沉淀的入口,更没有强制沉淀的机制。知识库解决的就是这个入口问题,让“记录”变成团队默认动作,让“查找”变成搜索框里的一次回车。
1.2 主流方案横向对比
在确定 Wiki.js 之前,我快速过了一遍市面上的主流方案,包括商业产品和开源项目。这里把当时的核心对比列出来,方便你做同样判断时有个参照:
| 方案 | 部署方式 | 内容格式 | 权限体系 | 核心成本 | 适合场景 |
|---|---|---|---|---|---|
| Confluence | 云版 / 私有化 | 所见即所得为主 | 强大 | 按用户收费,私有化部署重 | 规模型团队、流程成熟的企业 |
| Notion | 纯云 | 块编辑器 | 基础权限可用 | 按成员订阅 | 小团队、个人知识管理 |
| MediaWiki | 私有化 | 源码 wiki | 有但偏旧 | 免费,维护成本偏高 | WordPress 同量级的重 Wiki |
| BookStack | 私有化 | 所见即所得 | 有 | 免费,生态较小 | 偏文档书籍式组织 |
| Wiki.js | 私有化 | Markdown | 精细 ACL | 免费,Node.js 单服务轻量 | 技术团队、快速落地、长期沉淀 |
这个表格里我标出了 Wiki.js 的两个关键差异:Markdown 原生支持和轻量部署。技术团队的人写 Markdown 几乎没有学习成本,代码块、表格、引用都直接用文本表达,跟 Git 工作流也天然契合。另一个差异是 Docker 单容器加 PostgreSQL 就能跑起来,不像 Confluence 那样要一整套 Java 环境和更大的服务器资源。
1.3 Wiki.js 的独特优势与适用边界
Wiki.js 底层是 Node.js 写的,前端和后端都足够轻,官方镜像只有几百 MB 级别,跑起来的内存占用通常控制在 200~400 MB 之间,普通 1 核 2G 的小服务器完全带得动。这一点对于我们这种不想为知识库单独加预算的团队来说非常友好。
更难得的是它的能力边界不窄:支持完整的多语言界面(官方自带简体中文),内置可视化编辑器也支持 Markdown 源码模式,有细致的用户权限分组,可以接 PostgreSQL 全文搜索,还能把内容同步到 Git 仓库做版本管理。对开发者团队来说,这些特性叠加起来基本覆盖了“记录—检索—权限—追溯”的全链路。
不过它也有适用边界。如果你的团队以非技术背景为主,接受不了 Markdown 语法,更习惯像写 Word 一样“指哪打哪”的编辑体验,那 Wiki.js 的编辑器虽然已经做得不错,但他们的学习成本仍会比 Notion、Confluence 高一些。我的建议是:先看团队构成,再看功能列表。技术团队、产品团队混合场景下,Markdown 通常不是障碍,反而是加分项。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 部署前要想清楚的三件事
很多人一上来就 docker run 把容器拉起来,结果后面发现数据库选错了、附件存到了容器里、手机在外面访问不了,又推倒重来。部署 Wiki.js 之前,有三件事值得先想明白,每件事都会影响后续的维护成本。
2.1 数据库选择:PostgreSQL 是默认答案吗
Wiki.js 支持 PostgreSQL 和 SQLite 两种数据库。官方推荐用 PostgreSQL,这个推荐是有道理的。SQLite 适合极轻量的个人试用、本地跑一跑验证功能,但一旦你准备让团队正式使用,并发写入、数据安全、备份恢复、全文搜索这些需求会立刻暴露 SQLite 的短板。PostgreSQL 在这些方面的成熟度完全是另一个量级,而且 Wiki.js 的全文搜索功能在 PostgreSQL 上可以直接复用其内置的全文索引,不需要额外搭 Elasticsearch。
所以我的结论很直接:正式落地直接选 PostgreSQL,别犹豫。只有一种情况我会建议用 SQLite——你只是在自己的笔记本上跑个 demo,连外网都不打算暴露。哪怕是三五人的小团队,我也推荐 PostgreSQL,因为你不知道半年后这个知识库会长到多大。
2.2 图片与附件存储
Wiki.js 的附件默认存在本地文件系统,也就是容器内的 /wiki 目录。还有一套 Storage 模块机制,可以把上传的文件放到 S3、阿里云 OSS、腾讯云 COS、Google Cloud Storage 这类对象存储上。
我们的经验是:团队规模不大、附件量可控时,本地存储加定期快照就够了。但如果你上传教学视频、设计稿源文件这类大体积附件,或者服务器磁盘比较紧张,就一定要提前接对象存储。这个决策要在部署初期就做好,因为后期迁移存储后端虽然可行,但需要重新上传或同步已有附件,操作繁琐且容易遗漏。另一个细节是:无论用哪种存储,都要定期确认 client_max_body_size 这类上传大小的限制,默认的 Nginx 限制只有 1MB,传两张截图都能被拒绝,这个坑我在后面会专门说。
2.3 “随处可用”的访问链路规划
这里说的“随处可用”,对我们团队有三层含义:一是多端可用——办公室电脑、家里的笔记本、手机浏览器都能打开;二是随时随地可用——不限于局域网,出差在外面也要能正常访问;三是内容可离线兜底——万一网络不稳定或服务暂时不可用,重要的文档还能从别的渠道拿到。
要实现这三层,部署时就要把网络路径设计好。内网访问最简单,服务器开个端口就行;公网访问则需要域名加 HTTPS,再通过 Nginx 反向代理把流量转给 Wiki.js 的 3000 端口;手机端则靠 Wiki.js 自带的 PWA 特性和官方移动端 App 解决。Git 同步能力还可以做“离线兜底”——把所有文档镜像到 Git 仓库,即使 wiki 服务完全挂掉,git clone 一份下来也能随时查阅纯文本文档。这几层我会在后面的实操部分分别展开。
3. 从零到访问:完整部署实操记录
这一节是整篇最硬核的部分,按我实际的部署顺序一步步走,你照着抄基本不会出错。环境说明一下:服务器是 Ubuntu 22.04,域名提前解析到了服务器 IP,防火墙已经放行了 80 / 443 / 8080 端口。
3.1 服务器环境准备
首先更新系统并安装 Docker 和 Compose 插件。如果你服务器上已经装过 Docker,可以跳过前几步,但建议确认一下版本,太老的版本对 Compose 语法支持不完整。
bash复制sudo apt update && sudo apt upgrade -y
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update && sudo apt install -y docker-ce docker-compose-plugin
sudo systemctl enable --now docker
装完后验证一下:
bash复制docker --version
docker compose version
我建议直接在服务器上建一个干净的目录专门放 Wiki.js 相关文件,比如 /opt/wikijs,所有配置和备份都围绕这个目录做,便于管理。
3.2 编写 docker-compose.yml
进入 /opt/wikijs,创建 docker-compose.yml 文件。这个编排里有两个服务:db 负责 PostgreSQL,wiki 负责 Wiki.js 本体。我把密码、数据库名统一写在环境变量里,方便一眼看懂。
yaml复制services:
db:
image: postgres:15-alpine
container_name: wikijs-db
restart: unless-stopped
environment:
POSTGRES_DB: wiki
POSTGRES_USER: wiki
POSTGRES_PASSWORD: wikijsrocks
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U wiki"]
interval: 10s
timeout: 5s
retries: 5
wiki:
image: ghcr.io/requarks/wiki:latest
container_name: wikijs
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "8080:3000"
environment:
DB_TYPE: postgres
DB_HOST: db
DB_PORT: 5432
DB_USER: wiki
DB_PASS: wikijsrocks
DB_NAME: wiki
volumes:
- wiki-data:/wiki
volumes:
db-data:
wiki-data:
简单拆解几个关键点:
DB_TYPE必须写成postgres,Wiki.js 会据此选择驱动类型。depends_on里我加了condition: service_healthy,确保数据库完全就绪后 Wiki.js 再启动,否则容易出现“数据库连不上”的假性故障。wiki-data:/wiki这个卷保存配置文件、上传的附件等本地文件,不挂的话容器一删数据就没了。
启动命令很简单:
bash复制sudo docker compose up -d
等几秒后看日志:
bash复制sudo docker compose logs -f wiki
看到 HTTP Server listening on port 3000 之类的输出,就说明服务起来了。这时候用浏览器访问 http://服务器IP:8080,应该能看到 Wiki.js 的欢迎页面和初始化向导。
3.3 初始化、管理员配置与语言设置
首次访问会进入安装向导,一步步设置管理员邮箱、密码、站点名称。这里我要提醒三个细节:
- 管理员邮箱一定要用真实、长期可控的地址,密码找回和后续登录都依赖它。
- 站点名称建议一次想好,这个名称会显示在浏览器标签页、邮件通知和 PWA 应用名称里,后改虽也可以,但会麻烦一点。
- 语言选“简体中文”,向导里有语言下拉框,直接切换即可。
初始化完成进入管理后台后,我建议立刻做两件事。第一,在“管理后台”的“系统设置”里把站点 URL 改成最终的域名(比如 https://wiki.example.com),不要让 Wiki.js 认为自己跑在 IP 加端口上,否则后续邮件、链接都可能生成错。第二,开启两步验证(2FA),管理员账户是知识库的最终控制者,这一步能挡掉很多风险。
3.4 域名绑定与 HTTPS:Nginx + Certbot
如果只在局域网用,IP:8080 就够了。但要做到“随处可用”,域名加 HTTPS 几乎是必需的。HTTPS 不仅加密传输,还能让 PWA 的安装能力生效——浏览器只有在 HTTPS 环境下才允许把站点“安装”到桌面或手机。
先安装 Nginx 和 Certbot:
bash复制sudo apt install -y nginx certbot python3-certbot-nginx
然后新建一个 Nginx 站点配置 /etc/nginx/sites-available/wiki.conf:
nginx复制server {
listen 80;
server_name wiki.example.com;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
注意 client_max_body_size 50m,刚才提到的上传坑就在这里。不设置的话,默认 1MB 的请求体上限,传一张高清截图或一个小附件就会被 Nginx 直接拒绝,报 413 错误。
软链接启用并申请证书:
bash复制sudo ln -s /etc/nginx/sites-available/wiki.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d wiki.example.com
Certbot 会自动改写 Nginx 配置、加入 HTTPS 跳转和证书续期任务。完成后访问 https://wiki.example.com,一切正常。
3.5 移动端与 PWA:把知识库装进手机
Wiki.js 从 2.5 版本起就提供了官方移动端 App,iOS 和 Android 都能装。App 里直接填站点地址、账号信息就能登录浏览,体验比浏览器里缩放页面好很多。团队成员外出时查资料,手机上点点就行。
如果你不想所有人都装 App,PWA 是更轻的选择。Wiki.js 默认支持 PWA,在 HTTPS 环境下,用 Chrome 或手机浏览器打开站点,地址栏或菜单里会出现“安装应用”/“添加到主屏幕”的选项,装完后桌面图标打开就是独立窗口,跟原生 App 观感非常接近。这个特性对我们清华不高的同事来说零学习成本,点一下安装就好。
到这一步,基础的“随处可用”链路已经通了:桌面浏览器、手机 App、PWA 三点覆盖。接下来就要解决“内容怎么组织得更好用”的问题。
4. 内容组织与协作体验调优
部署跑通只是开始,知识库真正的成败在于内容组织。一个 Wiki 如果目录混乱、权限不明、没有版本管理,最终只会变成另一个没人用的杂物间。这一节是我认为最值得花时间琢磨的部分。
4.1 命名空间与目录结构设计
Wiki.js 用“命名空间”组织页面,形式上就是路径前缀。比如 engineering/backend/architecture 这个页面就属于 engineering/backend 命名空间。命名空间可以嵌套,侧边栏会按树形结构展示,这是团队知识库最基本的信息架构。
我推荐的第一条原则:按业务域划分顶层命名空间,而不是按部门划分。按部门建目录,意味着不同部门之间的知识天然隔离,跨部门复用就断了;按业务域建目录,比如 engineering、product、operations、company-handbook,大家找东西时先想“这是什么业务域”,而不是“这属于哪个部门”。
我们实际跑了一年的结构大致如下:
text复制home/ 首页与导航入口
engineering/
backend/ 后端设计文档、接口规范
frontend/ 前端组件规范、工程实践
devops/ 部署、CI/CD、监控记录
playbook/ 各类故障复盘与处理手册
product/
research/ 用户调研、竞品分析
specifications/ 需求与原型说明
operations/
playbooks/ 运营活动执行手册
company-handbook/ 公司制度、入职指南、报销流程
这套结构的好处是新人入职后,按“业务域”顺着目录就能把一个领域的来龙去脉读完。我们不追求完美分类,只保持一个页面只属于一个命名空间,避免同一内容分散到多个位置。
4.2 编辑器的几个细节技巧
Wiki.js 默认的编辑器是可视化编辑模式,工具栏支持标题、表格、代码块、图片等,对不熟悉 Markdown 的同事友好。但对常写技术文档的人,我建议在编辑器右上角切到“Markdown 源码”模式直接写,速度更快。
几个提升效率的具体细节:
- 代码块支持语言高亮,写 Python、JavaScript、Shell 时直接指定语言,方便阅读和复制。
- 页面内可以引用其他页面,用
[[页面路径]]或者链接语法就能做双链式跳转,适合梳理文档间的关联关系。 - 页面底部可以加标签(tags),比如
#数据库、#故障复盘、#新手上路,标签是搜索之外的另一种发现路径,比文件夹分类更灵活。 - 编辑过程中右上角的“预览”按钮即时查看渲染效果,保存前先确认表格和代码块没被弄乱。
团队如果希望每个页面都带人负责,可以在首页放一张“文档地图”,列出各命名空间的责任人。知识库持续维护的关键不是工具多强大,而是每个模块有人认领。
4.3 权限分组:谁看、谁写、谁管
Wiki.js 的权限模型是“组 + 页面路径规则”。默认有 管理员、编辑者、成员、访客 等角色,你可以自定义组,比如“后端组”“运营组”。权限既可以在“页面路径”级别精细控制(比如 /engineering 只允许对应组编辑),也可以全局统一控制。
我的建议是分三层:访客只读公开页面,成员可创建和编辑常规页面,管理员负责系统设置和敏感命名空间。对内部知识库来说,权限不应卡得太死,否则又会出现“想帮忙编辑文档但没有权限”的尴尬。我们只在两类内容上做了收紧:一是公司制度类,只放开给人事和管理员;二是故障复盘类,写入权限限定在当事人小组,避免外部干扰关键记录。
这里有个值得记住的规则:权限规则按路径前缀匹配,/engineering 的规则会作用于其下所有子页面。配置时一旦发现页面访问异常,先检查有没有更高层级的规则把它覆盖了。
4.4 Git 同步:版本历史的双保险
Wiki.js 内置了 Git 存储模块,可以把所有页面内容实时或定时同步到一个远程 Git 仓库。开启方式在管理后台的“存储”模块里,填入 Git 仓库地址、分支和认证信息,然后设置同步间隔。
这个功能的价值远超“备份”两个字。首先,每次编辑提交都对应一次 Git 提交,配合 Wiki.js 自带的页面历史,你能精确看到任何一版改写的前后差异,误删误改都能快速回滚。其次,任何人拿到 git clone 的副本,都等于拥有一份完整的离线文档库,这在服务故障或网络不通时是救命稻草。我们内部约定:知识库是线上可交互的 Wiki,也是 Git 仓库里的纯文本内容,两条线互不干扰、互为备份。
需要提醒的是,开启 Git 同步前先把远程仓库建好并确认认证有效,否则模块会同步失败并反复重试,日志里全是报错。同步方向默认是以 Wiki.js 为准推送到远端,不要在远端手动修改后强制推送回来,两边会产生冲突。
5. 常见问题与排查实录
这一部分整理的是我们运维过程中真实遇到的坑,以及对应的排查思路。很多问题官方文档里提到过,但藏得比较深,网上搜出来的都是零散回答,我汇总成一张速查表和两套标准流程,方便你直接对着操作。
5.1 高频问题速查表
| 现象 | 常见原因 | 解决方式 |
|---|---|---|
| 安装向导打不开 | 端口被防火墙拦截 | 检查服务器安全组,放行 8080 或最终对外端口 |
| 容器起来又重启,日志提示数据库连不上 | depends_on 未写健康检查;数据库未就绪 |
加上 condition: service_healthy,或等待数据库初始化后手动重启 wiki |
| 上传图片报 413 错误 | Nginx 默认 client_max_body_size 过小 |
在站点配置里加 client_max_body_size 50m; 后 reload |
| 搜索不到已存在的内容 | 全文索引未建立或过期 | 管理后台“搜索”设置里执行重建索引 |
| 页面显示 502 Bad Gateway | 反向代理未起来或端口写错 | 确认 Nginx 配置的 proxy_pass 指向正确端口,必要时 sudo systemctl reload nginx |
| 手机/PWA 无法安装 | 站点不是 HTTPS | 用 Certbot 申请证书,保证通过域名访问 |
| 忘记管理员密码 | 不可用常规方式找回 | 在容器内用官方 CLI 工具重置,操作前务必先备份数据库 |
| 页面权限同事看不到 | 命名空间 ACL 规则冲突 | 检查上级路径的权限规则,逐层排查页面归属组 |
这张表里最常出问题的就是 413 和 502 这两个,都跟 Nginx 配置相关。建议部署 Nginx 反代时就顺手把 client_max_body_size 写上,省得后面还要改配置、 reload、再让同事重新上传。
5.2 备份与升级的标准流程
知识库最怕数据丢失,备份习惯必须从第一天建立。我们的标准备份方案是“数据库 + 文件卷”双路径:
bash复制# 备份数据库
sudo docker compose exec db pg_dump -U wiki wiki > /opt/wikijs/backup/wiki_$(date +%F).sql
# 备份文件卷(附件 + 配置),用 tar 快照
sudo tar czf /opt/wikijs/backup/wiki_vol_$(date +%F).tar.gz -C /var/lib/docker/volumes wikijs_wiki-data
数据库备份可以每天定时跑,文件卷备份可以一周一次。如果开启了 Git 同步,那文档内容本身已经多了一层实时备份,重点确保附件目录和数据库不丢即可。
升级 Wiki.js 的流程我同样固定下来了:先备份数据库和文件卷,然后 docker compose pull wiki,再 docker compose up -d 重建容器。升级后第一件事是去管理后台触发一次数据库迁移确认,再随机抽几个页面检查渲染是否正常。整个过程十分钟以内,跑了一年多没出过事故。核心原则就一条:升级之前,备份永远先做,不要嫌麻烦。
5.3 几个值得记住的调优经验
最后补充三个不属于“故障”但很影响体验的经验。
第一个是全文搜索的调优。Wiki.js 用 PostgreSQL 的全文搜索做默认方案,内容量上来之后建议在管理后台重建索引并关注分词效果。中文分词的精细程度有限,搜中文关键词时适当少敲几个字反而命中更多。要是团队内容量特别大,可以接入 Elasticsearch,但对大多数团队来说,内置方案足够。
第二个是附件目录的体积控制。我们早期同事习惯把截图原图直接传上去,半年卷了十几个 GB。后来约定:图片尽量压缩后再传,超过 10MB 的文件一律走对象存储或公司网盘,只把链接放进 Wiki。这个约定让服务器磁盘压力小了很多。
第三个是多语言设置的细节。Wiki.js 界面切到简体中文后,有些系统邮件模板仍然是英文。如果有同事不习惯,可以在管理后台的本地化设置里再调一遍邮件模板语言,或者把邮件模板中关键字段核对一遍,避免通知发出去了同事不知道在说什么。
结尾
大半年跑下来,我最大的体会是:知识库不是“装一个软件”就完事,它更像一个需要持续浇水的园子。Wiki.js 负责把土壤和灌溉系统搭好——部署、权限、搜索、Git 同步,这些基础设施它都替你考虑到了;但真正的养分,还是每个团队成员的每次记录、每次复盘、每次把经验固化进页面的动作。
如果你正准备搭建团队知识库,我建议从最小的闭环开始:先部署一套 Wiki.js,把新员工入职手册和最近三个踩坑复盘放上去,让团队切实感受到“搜一下就有答案”的体验。当大家发现知识库真的能帮自己省时间之后,内容自然会越沉淀越多,知识孤岛也就慢慢瓦解了。
