团队知识库不交 SaaS:Outline 自托管 + OIDC 登录实测(附 Wiki.js 对比)
2026-08-16 · DevCraft Studio
不想再给 Notion/Confluence 按人头交订阅费?这篇手把手教你在 2 GB 小机用 Docker Compose 把 Outline(Postgres+Redis+Authentik OIDC)跑起来,讲清新手最怕的"必须配 OIDC"怎么破,并和 Wiki.js 的 Git 取向做个实在对比。
延伸阅读
更多相关攻略推荐:2026 独立站 PCI-DSS 自查清单:SAQ A 还是 A-E、2026 只选月付 VPS:不锁年付、随时退的试错策略、2026 海外仓/ERP 系统自建部署:独立服务器还是云 VPS?、2026 实测:VPS 上自托管 AI 编程助手——Continue、【知识库自托管 02】2026 实测:VPS 自托管 Anythin。
为什么要在 VPS 上自建团队知识库
Notion、Confluence 用着顺手,但每个座位每月都在扣费。一个 20 人的小团队,Notion 商业版一年就要两千多刀;更难受的是数据躺在别人服务器上,说封就封、说改隐私条款就改。Outline 是目前最接近 Notion 体验的开源自托管知识库,实时协作、Markdown、斜杠命令一应俱全,GitHub 上 30k+ stars,2026 年还在稳定发版。把它架在自己的 VPS 上,团队文档的"数据主权"就回到了你手里——别人进不去,你随时能整体打包导出。
这篇文章不跟你讲虚的,就按"便宜小机 + Docker Compose"的路线,从装环境到接身份认证一步步走,最后再和另一个热门选项 Wiki.js 掰扯清楚,帮你判断到底该选谁。
硬件怎么选:2 GB 小机能跑 Outline 吗
Outline 官方说最低 2 GB 内存、10 GB 磁盘就够。但要注意,它不是一个单容器:PostgreSQL 约占 200 MB,Redis 约占 50 MB,Outline 的 Node 进程空闲 200 MB、协作高峰能冲到 400 MB。如果你还把 Authentik 也塞在同一台机器上当 OIDC 身份源(Authentik-server 空闲约 450 MB、worker 约 150 MB),整机常态就能吃掉 1.2 GB 左右。
- 2 GB VPS:能跑,但务必开 1–2 GB swap,否则协作高峰有被 OOM 杀掉的风险。
- 4 GB VPS:推荐档,Outline + Authentik 同机毫无压力,长期更省心。
- 磁盘:系统 10 GB 起步,文档附件另算,20 GB SSD 比较舒服。
小团队想省钱,像 RackNerd、CloudCone 这类年付几刀的 KVM 小机就够试水;Vultr 按小时计费,适合先开一台 2 GB 的验证流程、跑通再决定长期机型;预算稍宽、想要更稳的内存余量,Contabo 的 2 GB 档给的 CPU 和流量都很实在。我们下面按"2 GB + swap"来讲,省下的钱就是利润。
再强调一句内存账:Outline 本体 + Postgres + Redis 大约 650 MB,Authentik 再吃约 600 MB,加上系统自身 200–300 MB 和 Docker 开销,2 GB 机器空闲时就已经比较满。所以 swap 不是可选项而是必选项,2 GB swap 能让你在协作峰值时不至于被内核杀进程。如果预算允许,直接上 4 GB 会省掉所有提心吊胆——这类机器在 RackNerd、CloudCone、Contabo、Vultr 上每月也就几刀到十几刀的差别。
第一步:装好 Docker 与目录骨架
选一台 Ubuntu 22.04+ 的机器,先装 Docker 和 Docker Compose 插件:
apt update && apt install -y docker.io docker-compose-plugin建一个干净的工作目录,所有配置都丢进去:
mkdir -p ~/outline && cd ~/outline先生成两个密钥,Outline 要求 SECRET_KEY 和 UTILS_SECRET 必须是正好 64 位十六进制(用 openssl rand -hex 32 生成,千万别用 -base64,否则启动会报 "SECRET_KEY must be exactly 64 hexadecimal characters")。
openssl rand -hex 32 # 生成 SECRET_KEY openssl rand -hex 32 # 生成 UTILS_SECRET顺手开个 swap 以防万一:
fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile还有一个前置条件必须说在前面:Outline 需要一个真实域名和 HTTPS,它不接受裸 IP 访问,URL 变量必须是带 https:// 的完整地址。生产环境请用 Caddy 或 Nginx 做反代并自动签发证书,把 3000 端口挡在公网后面。Caddy 的配置文件只要几行:把 wiki.你的域名.com 反代到 localhost:3000 即可,证书自动续。开发自测时可以先把 FORCE_HTTPS 设为 false 用 http 跑通流程,但上线一定要开 HTTPS。
第二步:用 Docker Compose 拉起 Postgres + Redis + Outline
把下面这份 docker-compose.yml 写进工作目录。注意几个新手必踩的坑:PGSSLMODE 必须设 disable(compose 里的 Postgres 没开 TLS,不设会连不上);Outline 容器要等 Postgres 和 Redis 都 healthy 才起;FILE_STORAGE 我们先图省事用 local 本地盘。
services: postgres: image: postgres:16-alpine environment: POSTGRES_USER: outline POSTGRES_PASSWORD: 你的强密码 POSTGRES_DB: outline volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U outline"] interval: 10s retries: 5 redis: image: redis:7.4-alpine volumes: - redisdata:/data healthcheck: test: ["CMD", "redis-cli", "ping"] outline: image: outlinewiki/outline:1.6.1 depends_on: postgres: condition: service_healthy redis: condition: service_healthy ports: - "3000:3000" environment: SECRET_KEY: 你的64位hex UTILS_SECRET: 你的64位hex DATABASE_URL: postgres://outline:你的强密码@postgres:5432/outline PGSSLMODE: disable REDIS_URL: redis://redis:6379 URL: https://wiki.你的域名.com PORT: 3000 FILE_STORAGE: local FILE_STORAGE_LOCAL_ROOT_DIR: /var/lib/outline/data OIDC_CLIENT_ID: 稍后填 OIDC_CLIENT_SECRET: 稍后填 OIDC_AUTH_URI: https://sso.你的域名.com/application/o/authorize/ OIDC_TOKEN_URI: https://sso.你的域名.com/application/o/token/ OIDC_USERINFO_URI: https://sso.你的域名.com/application/o/userinfo/ OIDC_DISPLAY_NAME: Authentik OIDC_SCOPES: openid profile email volumes: - outline-data:/var/lib/outline/data volumes: pgdata: redisdata: outline-data:把 OIDC 那几行先留着占位,等 Authentik 建好应用再回填。配置可以直接写死在 compose 里,也可以抽成 .env 用 env_file 引入,写完先别急着重启,下一步把身份源接上。
第三步:配 Authentik 当 OIDC 身份源(新手最容易卡的一步)
Outline 没有本地账号体系,必须接一个 OIDC/OAuth 提供方——这是劝退新手的最大门槛。自己架一个 Authentik 最通用,还能顺手给以后别的自托管应用当统一登录。Authentik 的部署不展开,假定它已经跑在 sso.你的域名.com,并且前面有 HTTPS 反代。
- 进 Authentik 后台 → Applications → Providers → Create,类型选 OAuth2 / OpenID Provider。
- Client type 选 Confidential,Authorization flow 用默认的 explicit consent。
- Redirect URIs 填 https://wiki.你的域名.com/auth/oidc.callback(这个回调地址写错是最常见的登录失败原因,少一个斜杠都不行)。
- 保存后记下 Client ID 和 Client Secret,回填到 Outline 的 OIDC_CLIENT_ID / OIDC_CLIENT_SECRET。
- 再到 Applications → Applications 建一个应用,把上面的 provider 绑上去,Launch URL 填 https://wiki.你的域名.com。
一个隐蔽坑:Outline 默认只让"邮箱域名匹配"的用户自动入站。如果你的 Authentik 用户邮箱后缀和预期不一致,登录会卡在授权后没反应。要么在 Outline 后台把允许域名配好,要么先拿管理邮箱登录。另外 OIDC_USERNAME_CLAIM 默认是 preferred_username,想用邮箱识别就改成 email。
进阶一点:如果你以后还想让 Authentik 同时给 Plane、Gitea 等别的应用做统一登录,可以在 Authentik 里建一个组(比如 engineering-team),把团队成员都加进去,再在每个应用上绑定"必须属于该组"的策略。这样加一个人进组就同时开通所有应用,踢出组就一键回收,运维清爽很多。Scope 保持 openid profile email 通常就够了,别乱加,免得 userinfo 返回字段对不上。
第四步:上线、登录与实时协作实测
一切就绪后拉起整个栈:
docker compose up -d docker compose logs -f outline第一次启动 Outline 会自动跑数据库迁移,日志出现 Listening on :3000 就说明活了。打开 https://wiki.你的域名.com,页面上会有一个 "Authentik" 登录按钮,点它跳去 Authentik 授权。第一个登录的人自动成为管理员,记得先去 Settings → Details 改工作区名称、去 Security 里限制允许注册的邮箱域名、关掉不必要的公开分享。
实测协作:拉两个同事同时打开同一篇文档,能看到彼此的彩色光标实时移动,输入即时同步,靠的是 Redis 的 pub/sub 在背后转发。这就是 Outline 比传统 wiki 爽的地方——像在共享一个 Notion 页面。分享文档也很简单,文档右上角 Share 生成只读公开链接,适合对外发 API 文档或产品手册。要接 CI 发文档,Settings → API 里生成 token,用 REST API 推上去就行。
权限模型也值得花两分钟搞清楚:Outline 的内容组织单位是"集合(collection)",集合上能设公开/私有,文档级别还能再细分读写。新同事第一次用 Authentik 登录后会自动建号,但默认不一定进得了某个集合,需要管理员在集合里手动加人,或者配置"新用户自动加入默认集合"。小团队图省事可以直接把核心集合设为团队成员可见;涉及薪酬、合同这类敏感内容,单独建私有集合并只拉相关人。
文件存储:本地盘还是 MinIO(S3)
上面示例用了 FILE_STORAGE=local,附件存在 Outline 容器卷里,备份直接拷卷就行,最简单。但官方更推荐 S3 兼容存储,方便横向扩展和对象存储备份。自己在同一台机器跑个 MinIO 也行:起一个 minio 容器,建一个 outline 桶,把 AWS_S3_* 系列变量填好、FILE_STORAGE 改成 s3 即可。2 GB 小机用本地盘完全够小团队,等附件多了再换 S3 不迟。提醒一句:FILE_STORAGE_UPLOAD_MAX_SIZE 默认约 25 MB,传大文件记得调大。
备份策略顺带提一嘴:本地盘方案下,定期 docker compose exec postgres pg_dump 出 SQL,连同 outline-data 卷一起打包,就是一份完整备份;用 S3/MinIO 时则连桶一起同步。恢复时先建库、导入 SQL、再把卷挂回去,基本能原地复活。别等机器真崩了才想起来没备份——知识库一旦丢,比丢代码还疼,因为很多"为什么当初这么配"的上下文只存在于此。
Outline vs Wiki.js:一个要 Git,一个要协作,怎么选
很多人会在 Outline 和 Wiki.js 之间纠结,本质区别就一句话:Wiki.js 把内容当代码管(双向 Git 同步),Outline 把内容当协作文档管(实时多人编辑)。
- 身份认证:Wiki.js 自带本地账号,还能接 15+ 种登录方式,开箱即用;Outline 强制外置 OIDC/OAuth,没 IdP 就进不去。
- 协作:Outline 原生实时协作,Wiki.js 没有多人同编。
- 存储取向:Wiki.js 支持把页面双向同步到 Git 仓库,文档能走 PR 评审;Outline 内容在 PostgreSQL 里,只有 Markdown 导入导出。
- 编辑器:Wiki.js 一个页面能切 Markdown / 可视化 / HTML 三种;Outline 是统一的块编辑器(类 Notion)。
- 许可证:Wiki.js 是 AGPL-3.0,Outline 是 BSL 1.1(源码可见但偏商业友好,采购时要留意)。
- 资源:两者空闲都只要两百兆上下,Outline 多一个 Redis 容器略重。
结论很直白:团队里写文档的不全是工程师、你最看重"大家同时改一份"的体验,选 Outline;文档要当代码评审、要进 Git、要本地账号省事,选 Wiki.js。我们这篇主角当然是 Outline。无论选哪个,RackNerd、CloudCone、Contabo、Vultr 上都能轻松跑起来。