本篇文章将介绍一款适用于个人或团队场景使用的开源 文档/ Wiki 软件,Outline。

在介绍如何部署使用之前,先聊聊为什么我会选择它。

写在前面

作为一个 Confluence 重度用户、前 EverNote 重度用户,我觉得有必要聊一下我对文档、笔记、Wiki 软件的一些看法。如果你仅对部署环境感兴趣,可以直接跳转文章下面的章节。

为什么要切换笔记/Wiki 软件

熟悉我的朋友了解我是 Confluence 重度用户,不少个人数据都存放在私有化部署的实例上,之前还额外购置了一台 NUC,用于低成本的跑这个服务,以及折腾过不少公开或还未公开的优化方案,关于部分 Confluence 部署和运维实战相关的文章,如果你感兴趣,可以翻阅这里

然而,在之前官方公布,不再出售授权,仅提供海外的在线 SaaS 服务,虽然我的授权会在 2022 年到期,但是考虑到长久使用,免不了要未雨绸缪,看看有没有更好的替代方案。

即将过期的 Confluence 授权

在试过国内外一众 SaaS 方案、以及部分类似 Joplin 支持私有化部署的方案、以及诸如 Obsidian 这类以本地工具为主的方案后,我最终选择了当下名气还不如它们的 Outline。

Outline 日常使用界面

为什么选择了 Outline

我目前已经使用这款软件两个月有余,在确认选择之前还是比较“折腾”和“犹豫”的。

影响我选择新工具的主要因素有三个:首先是书写体验要能够接近或优于 Confluence,接着是我能够拥有对输入内容的绝对管理权,能够放心的使用工具进行创作和内容管理,最后是使用工具的综合成本要相对低一些。这么组合下来,可供选择的“成品”就少了许多:

  • 书写体验主要由工具编辑器的响应交互能力决定,但是不仅仅由这部分决定,想要实现更多的套路,还需要前后结合,Confluence 迭代了十几年之久,在产品体验上确实做的挺全面的,导致切换到新的软件,总能感觉到新软件哪里缺了一些
  • 国内外不乏一些工具提供 SaaS 方案,有免费的,也有费用比 Confluence 高一些的,或是从资源配额上进行限制,或是从协作人数上进行限制,在预算之内能够解决问题自然是最好的,但是工具厂商为了“续费”、为了能持续盈利活下去,或者扩大账面上的数字拿更多的投资,很少做到完全将用户数据处置权完全交给用户,而且几乎没有能够将数据完全自托管管理的,这和 SaaS 生态模式和当前严峻的付费环境有关,软件和用户相互提防,挺没意思的。
  • 国内外也有一些开源或闭源的具备自托管能力的工具方案,但是这些方案起步时间比较早,产品策略上多数是对标早些时候类似 EverNote 这类纯粹的笔记软件,产品在内容创作场景和内容管理逻辑上和 Wiki 类产品差别还是有不少的,我比较反感“无效囤积”素材,尤其是软件默认逻辑可能就是如此。“知识库”类的工具光是解决了“书写”和“采集”的需求是不够的,还要解决“用”的问题呀。
  • 参考之前流行的 API As Service 方式做产品,参考 Confluence 做一个编辑器和这类 BaaS 服务(许多方案支持私有化部署)进行联动如何呢?之前曾看过 Confluence 迄今为止几个大版本的代码变化,虽然它是基于 tinyMCE 来定制的编辑器,编写门槛虽然不高,但是产品体验相关的细节,从前到后、方方面面的细节还是比较多的,换言之,工作量并不完全在前端,或许未来我会考虑折腾一把,但目前我还是想把精力尽可能聚焦在内容上,而不是造轮子。
  • 此外,Confluence 之前每年授权费用只有 10 刀,大概60块钱左右,相比较当前各种产品的费用,还是比较低的,如果考虑长期使用,采购一台小主机,容器启动起来就完事了。(相比较云主机同等配置资源要更便宜实惠一些)
  • 至于维护成本,Confluence 维护成本其实不算低,只不过在长时间维护过多个实例后,几乎踩遍了各种坑、手熟之后,倒也还好。如果再次选择方案,我会优先选择技术栈简单、代码开放的工具,如果不开放代码,那么在数据存储上需要有明确规范的工具。

在遍寻和尝试了各种软件之后,我将目光聚焦到了 Outline 上,一款目标是成为成长性团队使用的 Wiki 和知识库的软件,它直观的优点有这些:

  • Outline 是开源软件,软件由 Node 编写、数据库为 Postgres 9.x +、可以使用 Redis 作为缓存、部分存储使用 S3 兼容的对象存储协议。允许用户随意改动和进行私有化部署,所有数据由用户自己掌控,只要用户改造后不推出和官方一样的云服务进行商业化竞争即可。
  • 这款软件的编辑器类似简化版的 Notion,书写使用的快捷键和语法标记几乎和 Confluence 一致,切换使用几乎没有学习成本(除了个别快捷键)。
  • 软件界面中提供类似 Obsidian Publish 的悬浮卡片,能够在不切换上下文的情况下,快速了解工具内其他内容的概要,比较节约上下文切换时间。
  • 支持团队协作、以及分享功能,但是并不是强制要求使用的,对于个人使用场景、或小团队私密使用的场景,就显得非常友好了。
  • 另外,所有的文章数据均允许直接导出(默认格式为 markdown)、同样的,你也可以使用 API 或者编写自己的小工具快速进行整站内容的转换和导入。

当然,软件处于快速迭代期,缺点也有不少。我个人认为之所以有这些原因,主要的原因是 Slack 生态下对于这些问题都有解决和补充,从 Slack 生态剥离,产品逻辑自然需要进行调整,功能也自然就需要进行补充了:

  • 软件之前是重度绑定在 Slack 生态下的,很多功能和 Slack 深度绑定,私有化部署一度只支持使用 Slack 、GitHub 三方 OAuth 进行登陆授权。目前维护者正在着手解决身份验证相关的问题 ISSUE#1945,应该在接下来几个版本中,我们就能够看到实质的变化(在团队使用场景中)。
  • 软件之前对于自托管的支持并不是那么的友好,社区成员曾在 ISSUE#1881 下进行了大量讨论,在社区和作者的努力下,目测在下一个版本中,将有质的变化。我已经基于这些改动进行了一个“抢先版”的镜像,所以,你并不需要等待官方发布新版,就能提前进行体验啦。
  • 目前还不支持评论功能,官方正在着手解决。ISSUE#457
  • 目前对于附件管理功能也是缺失的,官方计划在未来两个版本中着手解决。ISSUE#859不过目前其实有挺多解决方案的,后面的文章中我会进行展开,聊聊最简单的方式。
  • 等等

虽然问题不少,但是这些问题对于个人和小团队使用来说,或许并不是最主要的问题,而且有非常多低成本解决方案。

接下来,我们来聊聊如何简单快速的私有化部署这套软件吧。

使用容器进行私有化部署

早些时候,我在 GitHub 上提交了示例代码:https://github.com/soulteary/docker-outline,为了降低配置复杂度,在这个例子中同样使用 Traefik 作为服务网关,如果你对 Traefik 还不熟悉,可以翻阅之前的内容进行了解《更简单的 Traefik 2 使用方式》,以及一些 Traefik 实战例子来加深理解。

在 Traefik 服务就绪的环境下,我们只需要几个步骤就能够将 Outline 跑起来。

步骤一:下载示例代码

首先,将示例代码下载到本地。

git clone https://github.com/soulteary/docker-outline.git

如果你在下载过程中遇到了网络问题,可以使用镜像地址:

git clone https://github.com.cnpmjs.org/soulteary/docker-outline.git

步骤二:创建你的配置文件

先复制一份配置文件,将新配置文件命名为 .env,修改其中你“介意”的地方:

cp .env.example .env

我个人推荐修改以下配置:

所有的域名相关的配置,使用你自己的域名进行替换。

DOCKER_MINIO_HOSTNAME=file.lab.com
DOCKER_MINIO_ADMIN_DOMAIN=file-admin.lab.com
SSO_SERVER_DOMAIN=sso.lab.com
DOCKER_ATTACHMENT_HOSTNAME=attachment.lab.com
DOCKER_OUTLINE_HOSTNAME=docs.lab.com

密钥相关的配置,你可以参考注释中的链接或生成方法,手动生成一份,如果你是在私有网络运行,不修改问题也不大。

# Select `Lowercase a-z and numbers` and 16-bit string length https://onlinerandomtools.com/generate-random-string
MINIO_ROOT_USER=6m2lx2ffmbr9ikod
# Select `Lowercase a-z and numbers` and 64-bit string length https://onlinerandomtools.com/generate-random-string
MINIO_ROOT_PASSWORD=2k78fpraq7rs5xlrti5p6cvb767a691h3jqi47ihbu75cx23twkzpok86sf1aw1e
MINIO_REGION_NAME=cn-homelab-1

DOCKER_POSTGRES_PASS=qTj5kwUEetmN

# You can use online tools to regenerate: https://www.uuidgenerator.net/
SSO_CLIENT_ID=b8c40013-cc03-4bc5-b3a5-6a31046fa415
SSO_CLIENT_SECRET=26272010-37d9-4bea-a58e-6b0a382d7626 

# Execute in the CLI `htpasswd -nb user pass`
DOCKER_ATTACHMENT_BASIC_AUTH=user:$apr1$8wC8avYf$Nhn0oTAvNjdw8FPROokGN.

# `openssl rand -hex 32`
OUTLINE_SECRET_KEY=64074328631d7ce618f554694ff7e83e820b9f7e14b13e4317893fed18e0b3c3
OUTLINE_UTILS_SECRET=04d7572e983ee6adfd77f8c77b61be8236a9e459fc9c1b7032ec278345638bcc

如果你希望使用你自己的用户名进行登陆,而非使用 SSO 服务默认使用的 username 用户进行登陆的话,则需要修改下面的配置,避免登陆被 Outline 拦截。

OIDC_ALLOWED_DOMAINS=company.ltd

默认的 SSO 使用的用户账号和邮箱,我在 soulteary/docker-sso-server 这个项目中有提到过,目前项目默认使用的用户配置信息如下:

  • 用户: username
  • 密码: password
  • 邮箱:username@company.ltd

如果你想定制生成属于你的信息,可以使用 授权协议在线生成工具 ,生成属于你的授权文件。

步骤三:启动应用

根据你的实际情况,创建一个属于 Outline 的虚拟网卡,让各种应用之间能够相对独立的进行数据通信,如果你已经创建过了,那么可以跳过这里,继续浏览如何启动应用。

docker network create outline

接着使用 docker-compose 选择各种应用配置,一键启动应用所需的各种服务:

docker-compose -f docker-compose.postgres.yml -f docker-compose.redis.yml -f docker-compose.minio.yml -f docker-compose.attachment.yml -f docker-compose.sso.yml -f docker-compose.outline.yml up -d

命令执行后,不出意外,你将会看到类似下面的日志输出:

Creating outline_minio    ... done
Creating outline-postgres ... done
Creating outline-redis    ... done
Creating linx-server      ... done
Creating outline          ... done
Creating sso-server       ... done

但是此刻我们还不能使用 Outline,服务首次启动后需要做一些初始化的操作,但是放心,这些操作都是自动化的。只需要稍等片刻,等待服务启动就绪就可以了。

我们,可以通过下面的命令来检查服务运行状态是否健康。

docker-compose -f docker-compose.postgres.yml -f docker-compose.redis.yml -f docker-compose.minio.yml -f docker-compose.attachment.yml -f docker-compose.sso.yml -f docker-compose.outline.yml ps   

当你看到类似下面的日志内容的时候(服务状态都展示 healthy),我们就能在浏览器中访问之前我们在配置中设置的域名,来使用 Outline 了。(本例中我设置的域名是 docs.lab.com

      Name                    Command                  State        Ports  
---------------------------------------------------------------------------
linx-server        /usr/local/bin/linx-server ...   Up (healthy)   8080/tcp
outline            docker-entrypoint.sh sh -c ...   Up (healthy)   3000/tcp
outline-postgres   docker-entrypoint.sh postgres    Up (healthy)   5432/tcp
outline-redis      docker-entrypoint.sh redis ...   Up (healthy)   6379/tcp
outline_minio      /usr/bin/docker-entrypoint ...   Up (healthy)   9000/tcp
sso-server         docker-entrypoint.sh ./main      Up (healthy)   80/tcp   

不出意外,你将看到类似下面的界面。

Outline 初始界面

因为使用了 SSO 登陆服务,所以我们继续来聊聊 Outline 的初次使用。

对 Outline 进行简单使用

在服务正常运行后,在浏览器中打开 Outline,点击使用 MySSO 登陆按钮,页面将会被跳转至本地运行的 SSO 服务。

默认的 SSO 登陆界面

在“步骤二:创建你的配置文件”提到过如何自定义用户名和密码,以及默认用户名和密码。我们使用设置好的账号密码登陆,将会被引导到 OTP 工具设置界面。

设置 OTP 工具

你可以使用任何你熟悉或者喜欢的工具,扫描二维码或者通过密钥建立完成 OTP 绑定,在今后首次登陆应用时,SSO 服务除了会向你询问账号密码之外,还会和你确认根据时间实时生成的这个 OTP 代码。从而增强你本地账户登陆的安全性和背后的应用数据访问安全。

我这里使用的是谷歌推出身份认证器(Google Authenticator),当然你使用微软、或者三方推出的也没有问题,毕竟是通用协议,用啥解析都行,甚至是“网页”,只要你用起来顺手就成。

配置完毕之后,点击蓝色的“确认”按钮,将会被要求输入第一次 OTP 代码。

首次确认 OTP 代码

因为首次使用时间太久,用于认证的参数过期,我们可能会被重新重定向到 Outline 的首页,这时放心的再次点击“使用 MySSO 继续”,稍等片刻就能看到 Outline 的“真身”了。

默认的 Outline 内容界面

软件界面非常简洁,功能分布也比较清晰,相信不用我过多介绍,你就能直接开始探索了,相信没有人能抵抗“开箱”的乐趣,所以基础使用部分,我就先不做展开了,自己探索出来的玩法才是“最香”的嘛。

不过,我猜使用者中一定有“英语苦手”,目前 Outline 中的中文已经是就绪状态,推荐点击左侧侧边栏的 “settings” 链接,进入设置页面,切换语言为中文。两个月前,我曾经对官方翻译进行了一部分更新,目前应该绝大多数内容都是中文了,如果还有漏网之鱼,欢迎联系我。

调整语言配置

此外,如果你对于默认的应用名称“Wiki”也有个性化的需求,可以修改设置界面里的“团队”名称,来完成内容更新。

更新团队名称

最后

这篇关于 Outline 的内容,虽然早在 7月末就在群里和大伙聊过,但是考虑到数据安全、运行稳定一直拖到了现在,在充分使用和验证后,这个坑应该会在本月进行完结。

下篇 Outline 相关的内容,我将展开聊下如何进行更细致的配置。

–EOF