站长的「第二大脑」为什么需要一个自托管的知识库
做站几年下来,你会攒下一大堆只有自己看得懂的东西:某台服务器的登录方式、某个服务的端口和路径、一段解决过三次的报错处理步骤、一篇写了一半的选题草稿、某个客户的对接记录、常用脚本的用法。这些东西现在大多散落在各个地方——桌面上的 txt、手机备忘录、浏览器书签、微信收藏、还有一些只存在于脑子里的记忆。
散着的直接后果是:真正要用的时候找不到。半年后服务器又出同样的故障,你只记得「上次好像搞过」,但翻遍所有地方都找不到那次的处理记录。
一个自托管的 Wiki 就是解决这个问题的。它把所有零散的知识集中到一个你自己掌控的站点里,有搜索、有目录、有版本历史、有多人协作,还不用把你的内部笔记交给第三方的云笔记服务。Wiki.js 是这类工具里做得比较全面的一个:界面现代、功能全、支持 Markdown、支持中文、自带全文搜索,而且部署不复杂。
本文把 Wiki.js 从零部署起来,讲清楚它和「直接用静态站」「用网盘放文档」的区别,以及数据库、搜索、反代这几个关键配置。
Wiki.js 的定位:它和那几种土办法的分界
先讲清楚它适合什么,避免你部署完发现其实用 markdown 文件夹就够了。
对比「本地 Markdown 文件夹 + 编辑器」:这是最轻的方案,优点是不依赖任何服务。缺点是只能在本地看,多设备同步要靠 Git 或网盘,而且没有统一搜索、没有权限控制、手机上看体验很差。当你的笔记超过一两百篇,纯文件夹就开始变得难用了。
对比「云笔记(印象笔记/Notion/语雀)」:这类工具体验好、开箱即用,但你的数据在人家服务器上,免费额度会限制,导出格式也未必干净,最要命的是哪天服务调整或者涨价你没法抵抗。对做技术的人,把自己的知识库放在别人的服务器上总有点不踏实。
对比「静态站点生成器(Hugo/VuePress)」:适合「输出型」的知识库——你写好了给别人看。但作为日常笔记工具,它每次更新都要重新构建、部署,流程太重,不适合随手记。
Wiki.js 处在一个中间位置:它比静态站灵活(网页上直接编辑,改完即存,不用构建),比云笔记可控(数据在你自己的 PostgreSQL 里,想导出随时导),比纯文件夹好用(搜索、目录、权限、历史版本都有)。
部署:PostgreSQL + Wiki.js 两个容器
Wiki.js 需要一个数据库,官方推荐 PostgreSQL。先建目录:
mkdir -p /opt/wikijs/{db,wiki-data}
cd /opt/wikijs
写 docker-compose.yml:
services:
db:
image: postgres:15-alpine
container_name: wikijs-db
environment:
POSTGRES_DB: wiki
POSTGRES_USER: wikijs
POSTGRES_PASSWORD: 换成你自己的强密码
volumes:
- ./db:/var/lib/postgresql/data
restart: unless-stopped
wiki:
image: requarks/wiki:2
container_name: wikijs
depends_on:
- db
environment:
DB_TYPE: postgres
DB_HOST: db
DB_PORT: 5432
DB_USER: wikijs
DB_PASS: 换成你自己的强密码
DB_NAME: wiki
ports:
- "127.0.0.1:3000:3000"
restart: unless-stopped
几个要点:
- 数据库密码要一致:
db服务里的POSTGRES_PASSWORD和wiki服务里的DB_PASS必须是同一个值,写错了会导致 Wiki.js 一直连不上数据库、卡在初始化界面。这是新手最常见的错误。 - 端口绑
127.0.0.1:Wiki.js 初始化后你需要设置管理员账号,但不要在这之前就把它暴露到公网。先绑回环,用 SSH 隧道进去完成初始化,再配反代。 - PostgreSQL 数据必须挂卷:所有内容都在这,忘了挂卷等于把知识库放进了易失内存里。
启动:
docker compose up -d docker compose logs -f wiki
初始化:用 SSH 隧道完成首次设置
因为端口绑在回环上,从本机做端口转发:
ssh -L 3000:127.0.0.1:3000 root@你的服务器IP
然后本地浏览器打开 http://localhost:3000。第一次访问会进入安装向导:
- 填站点 URL(先填临时的,比如
http://localhost:3000,后面配好反代再改成正式域名)。 - 填管理员邮箱、密码。这个账号就是你的超级管理员,密码要强。
- 设置完成后进入设置界面,把站点地址改成正式的
https://wiki.example.com。
注意这里有个坑:如果站点 URL 配错(比如留了内网的 localhost),后面从公网访问时会出现「点登录跳转到 localhost」或者「静态资源加载不出来」的问题。所以配好反代后,一定要回到「管理 → 常规」里把站点地址改成正式域名。
中文与富文本:把编辑器配到顺手
Wiki.js 支持多种编辑器,在「管理 → 编辑器」里可以设默认的。建议选 Markdown 编辑器(写代码的人最顺),或者它的可视化的 Visual Editor(不熟悉 Markdown 的人用)。
中文方面,Wiki.js 2.x 的内置界面已经支持简体中文,在「管理 → 本地化」里把语言切到 Chinese (Simplified) 即可。但有一个中文用户常踩的坑:全文搜索的中文分词。
Wiki.js 默认的数据库搜索引擎(Database - Basic)对中文支持不好,因为它按空格分词,而中文没有空格,结果就是中文搜索经常搜不到东西,或者结果很离谱。解决办法是换成对中文友好的搜索后端,或者在内容里适度使用标题和标签来辅助检索。如果搜索是刚需,可以考虑启用 PostgreSQL 自带的全文检索并配合合适的分词扩展,这一步配置相对麻烦,但对中文站是值得的。
实用建议:靠「目录 + 标签 + 规范的标题层级」来组织,比指望全文搜中文更可靠。 把每个主题做成一个页面,标题写清楚,标签打全,这样即使搜索弱一点也能靠导航找到。
Nginx 反向代理:WebSocket 必须放行
Wiki.js 的编辑界面和实时功能依赖 WebSocket,反代时如果不放行 Upgrade 头,会出现「页面能打开但编辑器用不了」或者「保存按钮一直转」的情况。
server {
listen 443 ssl http2;
server_name wiki.example.com;
ssl_certificate /etc/letsencrypt/live/wiki.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wiki.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# WebSocket 支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
}
配好后 certbot --nginx -d wiki.example.com 签证书,然后别忘了回 Wiki.js 后台把站点地址改成 https://wiki.example.com,很多人这一步忘了导致各种跳转异常。
备份:PostgreSQL 是唯一的重点
Wiki.js 的所有内容——页面、用户、权限、历史版本——全都在 PostgreSQL 里,所以备份的重点就是数据库本身。文件的备份反而简单(如果上传了附件,那部分要单独备份)。
写一个备份脚本:
#!/bin/bash BACKUP_DIR=/backup/wikijs mkdir -p "$BACKUP_DIR" STAMP=$(date +%Y%m%d_%H%M%S) docker exec wikijs-db pg_dump -U wikijs wiki \ | gzip > "$BACKUP_DIR/wiki_$STAMP.sql.gz" # 只保留最近 14 天 find "$BACKUP_DIR" -name "wiki_*.sql.gz" -mtime +14 -delete
把脚本放进 cron 定时跑。恢复时就是解压后用 psql 导回去。关键是要真的演练一次恢复流程——只备份不恢复演练,等于没备份,因为你不知道备份文件到底能不能用。
另外有个细节:直接 docker cp 复制 PostgreSQL 的 data 目录做备份是不安全的,因为在数据库运行中复制文件可能拿到不一致的快照,恢复后可能损坏。一定要用 pg_dump 这种逻辑备份,或者在停库的情况下用 pg_basebackup 做物理备份。
版本历史与权限:两个容易被忽略但很有用的功能
写知识库的时候,改错东西是常事——删了一段内容想找回来、或者想看看某个页面三个月前是什么样。Wiki.js 保留了每个页面的历史版本,在页面右上角能看到版本列表,随时可以对比和回滚。这一点比纯 Markdown 文件夹强太多,文件夹要么靠 Git(需要你会用),要么改了就改不回来。
权限方面,Wiki.js 支持按页面路径、按用户组做细粒度控制。个人用其实不复杂,但如果将来有别人一起维护——比如你和运营同事共享一部分内容,另一部分只有你能看——这个能力就很有用了。可以建几个组,把不同的目录挂给不同的组。个人自用可以全部设成只给管理员读写,不开放公开注册(在「管理 → 认证」里关掉本地注册,或限制注册需审批)。
六个常见的坑
- 数据库连接失败、卡在初始化:最常见是
DB_PASS和POSTGRES_PASSWORD不一致,或者数据库还没启动完 Wiki.js 就先启动了(可以给wiki加depends_on并考虑加健康检查等待)。 - 站点 URL 配了 localhost:导致从公网访问时登录跳转、静态资源全挂。配好反代后务必回后台改成正式域名。
- 中文搜不到内容:默认数据库搜索引擎对中文支持差,靠标签和目录组织弥补,或换用支持中文的搜索后端。
- 编辑器保存不了/一直转圈:Nginx 反代漏了 WebSocket 的
Upgrade头。 - 没备份,或者备份了没演练恢复:数据库是唯一的数据源,必须
pg_dump定时备份并验证可恢复。 - 装机后忘了设管理员强密码、没关公开注册:等于把自己的内部笔记站开放给全世界注册,先关注册再收尾。
小结
对个人站长来说,一个自托管的 Wiki 是「第二大脑」里最值得投入的一块基础设施:它把散落各处的技术笔记和行为经验收拢到一个你能完全掌控、能搜索、能追溯历史的地方。Wiki.js 用两个 Docker 容器就能跑起来,部署不难。
要点回顾:数据库密码两处要一致、端口先绑回环用隧道初始化、反代必须放行 WebSocket、配好后回后台改站点 URL、中文环境靠标签和目录组织、数据库定时 pg_dump 备份并演练恢复。做到这几步,你就有一个真正属于自己的知识库了——不会因为服务商改了政策就打不开,也不会因为换了台电脑就找不到。