像装应用一样轻松自建服务:YunoHost 使用指南
A version of this article appears on Sep. 27, 2023 on SSPAI as a member-only post. Learn more or subscribe
The article is permitted to be self-archived in the version as originally submitted for publication on the author’s personal website under CC BY-NC 4.0 pursuant to § 5.2(b) of the SSPAI Fellowship Contributor Agreement.
概述
自托管(self-hosting)是一个令很多人跃跃欲试,但又心怀畏惧的话题。尽管能以低廉成本用上品类丰富、高度自主的开源服务,但相应的代价就是需要付出大量时间精力来部署和配置。这将很多新手拦在了门外。
针对这个问题,很多教程会推荐使用 Docker 来绕过繁琐的部署流程。这固然不失为一种捷径,但也有一些不可忽视的缺陷,例如占用资源和空间较多、自主修改配置较麻烦等。从学习的角度来说,尽管表面上省事了,但也因此错过了实践软件包管理、服务器维护等基础知识的机会;一旦日后出现问题,「欠下的课总是要补回来的」。
YunoHost(意思是 Why you no host,不然呢?)提供了一个兼顾便捷和灵活的折中方案。
本质上,YunoHost 是基于 Debian 的发行版,但专门面向自托管开源服务的场景设计,不仅提供了美观、易用的网页端前后台界面,而且有一个社区维护的「应用商店」,把繁琐多变的服务部署流程简化为几次鼠标点击。
YunoHost 标志性的「元素周期表」风格前台首页
YunoHost 提供的软件选择非常丰富。截至本文写作时(2022 年 9 月),其软件目录共收录软件 388 种(归类为「低质量」或「失效」的应用不计),其中 191 种为安装运行均相当稳定的「高质量」软件。
我使用 YunoHost 已有近四年时间,这其间,它一直在稳定更新,收录的软件也越来越丰富;作为一款纯靠社区驱动的发行版,这难能可贵。前不久,YunoHost 刚获得一次大版本更新,将底层升级为推出不久的 Debian 11。因此,目前也是很好的「上车」时机。
接下来,本文就将结合使用经验,依次介绍 YunoHost 的安装和配置,并就服务安装、日常使用等方面提出建议。
(注:YunoHost 提供了一个全功能的演示服务器,你可以先充分尝试再决定要不要动手安装,也可以在执行关键步骤之前用来练手。)
上手指南:从系统安装到服务部署
第一步 准备安装环境
YunoHost 主要有两种安装方式:既可以下载完整的 ISO 镜像,直接在一台 x86 或 ARM 架构的裸机(包括树莓派等开发板)上全新安装;也可以先准备一个干净的 Debian 11 系统,然后运行安装脚本当作补丁安装。
考虑到公网访问的便利,本文重点演示第二种方式,在一台新创建的 VPS(云主机)实例上通过安装脚本安装。其实,对于局域网环境、实体硬件上安装的情况,大多数步骤和描述也可以套用,只是需要额外考虑公网转发的问题。
(注:YunoHost 官方提供了非常完整的安装指南,建议读者一并查阅;本文重在就疑难步骤给出补充和提示,并穿插解释相关背景,未必逐一重述具体步骤。)
首先,前往 VPS 服务提供商的面板,新建一个 VPS 实例。实例的配置参考如下:
- 操作系统:选择 Debian 11 (bullseye)。
- 配置:YunoHost 要求的最小配置是 512MB 内存和 16GB 硬盘空间,对 CPU 性能未作明确规定。经验上,主流 VPS 服务商的最低配置(即单核 CPU、1GB 内存和 20GB SSD 硬盘)足以运行一个博客加上两三个轻量服;但消耗较大的软件则需酌情升级配置,详见后文。
- 服务器位置:对于国外 VPS 服务,一般可以选择东亚和美国西部机房,延迟相对较低(一般情况,更细致的讨论超出了本文范围)。国内 VPS 服务基本没有访问延迟的顾虑,但下载软件包可能较慢,可能需要先行换用国内的镜像源。(具体步骤请参考相关镜像源的文档,例如 TUNA 源或阿里云镜像源,在此不赘述。)
使用 DigitalOcean 创建 VPS 的配置示例
第二步 运行安装脚本
创建完 VPS 实例后,以 root 用户身份登录(或用其他用户登录后运行 sudo su
切换为 root 身份),然后运行 YunoHost 的安装脚本:
curl https://install.yunohost.org | bash
(审慎起见,形如 curl | bash
的安装方式最好先审阅一遍源文件的内容。)
安装过程中,会询问是否允许安装程序覆盖现有的一些配置文件,使用方向键和回车选择 Yes 或 Install the package maintainer’s version 等选项,即接受 YunoHost 安装程序的更改。
此后的安装时间取决于实例性能,从几分钟到十几分钟不等。耐心等待,直到提示 YunoHost installation completed 即可。
第三步 配置默认域名
安装完成后,打开浏览器,直接访问 VPS 实例的 IP 地址(如果在局域网环境安装,可以使用保留域名 yunohost.local
)。
此时,大多浏览器会提示证书错误,这是因为目前尚未安装 SSL 证书,YunoHost 临时安装了一个自签名的证书,点击「继续访问」或类似按钮,忽略错误继续访问即可。
接下来需要为 YunoHost 配置域名(下称「默认域名」)。这里,你既可以注册一个 YunoHost 免费分配的子域名,也可以使用自己持有的域名,下面分别介绍。
方案 A:使用 YunoHost 免费分配的域名
如果你没有(或者不想占用)自己的域名,YunoHost 也非常贴心地提供了三种简洁好记的免费子域名:yourname.noho.st
、yourname.ynh.fr
或 yourname.nohost.me
,其中 yourname
是可以自主选择的部分。
如果想注册一个这样的子域名,则在设置默认域名步骤选择 I don’t have a domain name,填写注册表单即可;YunoHost 会自动完成相关的注册和 DNS 解析设置。(出于节约资源考虑,每台机器只能绑定一个免费域名。)
如果你想自托管多种服务,或许会顾虑一个子域名不够用。其实,只要你申请了一个免费子域名,它的所有下级子域名也都是属于你的,并且可以在 YunoHost 中直接使用。例如,你申请了 yourname.noho.st
,就可以用 blog.yourname.noho.st
来做博客,用 forum.yourname.noho.st
来做论坛。
不过,由于 YunoHost 毕竟只是一个社区项目,它对于域名的分配方式是不太「正规」的。如果后续遇到重装、迁移服务器等情况,需要解绑或更换域名,就需要……呃,去论坛的一个专门主题里发帖。虽然处理效率倒是不慢(经验上在一两个工作日内),但如果你顾虑这点,那就还是优先使用自有域名吧。
方案 B:使用自有域名
如果你已经有一个域名,并且希望将其用于 YunoHost,则选择 I already have a domain name,填写要分配给 YunoHost 的域名即可。
这里,你可以把整个域名都作为默认域名(如 yourname.tld
),也可以把它的一个子域名作为默认域名(如 ynh.yourname.tld
)。
显然,如果用自有域名作为默认域名,需要为其配置 DNS 解析。具体界面和步骤取决于你的 DNS 服务提供商,这里只介绍通用原则。注意,DNS 解析设置不一定要在添加域名之前就完成,也可以先添加域名再设置解析,只是在设置完成前无法用该域名访问 YunoHost。
为安装 YunoHost 目的,主要涉及的 DNS 记录包括:
- 必选:
- 为默认域名添加一条 A 记录指向 VPS 的 IPv4 地址。例如,将
ynh
(如分配整个域名,则填写@
)指向192.0.2.1
。 - 为默认域名添加一条 CAA 记录用于申请证书,设置其 authority(有的服务商为 value)为
letsencrypt.org
,tag 为 issue, flags 为128
。
- 为默认域名添加一条 A 记录指向 VPS 的 IPv4 地址。例如,将
- 可选:
- 如果希望将默认域名下所有未分配的子域名都解析到 YunoHost 面板,则再添加一条 A 记录,将
*.ynh
(如分配整个域名,则填写*
)也指向 VPS 的 IPv4 地址。 - 如果 VPS 支持 IPv6 并且希望启用,则添加一条 AAAA 记录,将
ynh
(如分配整个域名,则填写@
)指向 VPS 的 IPv6 地址。与上条类似,如果希望自动重定向未分配的子域名,则再添加一条 AAAA 记录,将*.ynh
(或*
)也指向 VPS 的 IPv6 地址。 - 如果希望安装即时通讯类服务(例如 Mattermost、Element)或者进行邮件收发,则还要添加一系列相关的 DNS 记录,具体可以参照官方文档中的示例。
- 如果希望将默认域名下所有未分配的子域名都解析到 YunoHost 面板,则再添加一条 A 记录,将
此外需要注意:
- 对于 TTL(即 DNS 记录的缓存时限),如果在初次配置时不确定以后是否会变更,可以暂时选一个较短的 TTL,待配置落定后再改成比较常见的 1 小时或「自动」。
- 有的 DNS 提供商支持 CDN 和 DDoS 防护功能(例如 Cloudflare 中的 Proxy status 选项),但在配置阶段启用这些功能可能导致解析更新不及时、访问错误等问题,建议先不要启用,后续再根据安装的服务类型有选择地启用。
下图演示的是用 Cloudflare 的 DNS 服务添加一条默认域名的 A 记录:
添加完默认域名后,安装向导会提示设置一个管理员密码,完成后,会自动跳转到后台页面。到这里,安装后的初始配置就告一段落了。
第四步 为域名安装证书
目前,我们还有一个遗留的域名问题没解决——默认域名的证书目前仍然是自行签署的,浏览器并不承认。为了解决这个问题,我们需要安装一个免费的 Let’s Encrypt 证书。
首先,在后台页面依次点击 Domains > [默认域名] > Certificate。
注意到此时 Install a Let’s Encrypt certificate 按钮是灰色无法点击的状态。这其实是 YunoHost 的一个流程设定:新添加的域名必须先诊断 DNS 配置是否完整,然后才能申请证书。
为此,点击按钮上方提示语中的 diagnosis page 链接(实际上就是跳转到后台页面首页的 Diagnosis 功能模块),耐心等待诊断完成。
如果你添加的域名是自有域名,很可能会看到结果页中有一些红色报错或黄色警告提示。但不用过于担心,先点开提示查看详情——这一般是因为 DNS 配置中缺少了一些上文列举的「可选」DNS 记录,例如 IPv6、电邮服务相关的记录等。
对此,根据提示信息补全相应的记录即可。当然,如果你确认用不上依赖这些缺失记录的服务,那么也可以直接忽略。
现在再回到 Certificate 页面,就会发现安装证书按钮可以点击了。安装完证书以后,再用浏览器访问默认域名就不会报错。(Let’s Encrypt 证书的有效期为 90 天,但 YunoHost 会在届满前自动续期,一般不用人工干预。)
第五步 添加前台用户
到目前为止,我们都是在后台页面操作,并且操作都是以管理员用户 admin 的身份做出的。但为了安装和使用各种软件,还需要创建至少一个普通权限的前台用户,用来登录前台页面。
为此,在后台首页点击 Users > New User,然后输入用户名、密码等完成创建。
第六步 安装应用
至此,我们就完成了全部的准备工作,可以正式开始安装软件了。这里,我们以自托管最常见的需求——搭建博客为例,演示如何安装 WordPress。
首先,你需要考虑用什么地址来托管服务。大多数软件都同时支持安装在 (a) 子域名(例如 blog.yourname.tld
)、(b) 子路径(例如 yourname.tld/blog
)或 (c) 子域名与子路径的组合(例如 www.yourname.tld/blog
)上,如何选择主要是一个偏好问题;但也有部分软件只支持用单独的子域名安装。
这里,我们假设你准备用子域名 blog.yourname.tld
来安装 WordPress。为此,需要将这个子域名添加到 YunoHost 中(使用子路径则没有这个步骤)。
方法是,在后台页面点击 Domains > Add domain,然后输入准备使用的完整子域名,点击 Add 即可。
如上文所述,如果你的默认域名是 YunoHost 提供的免费域名,那么相关的 DNS 配置会自动完成;如果你的默认域名是自有域名,那么需要为这个子域名添加一条指向默认域名的 CNAME 记录(本例中,即添加一条从 blog.ynh
指向 ynh.yourname.tld
的 CNAME 记录)。
接着,在 Domains 页面点击刚刚添加的子域名,按之前配置默认域名时相同的流程,完成诊断和添加证书。
准备好了子域名,现在就可以安装 WordPress 了。在后台页面点击 Applications > Install,进入 YunoHost 的软件目录。
在软件目录中,你可以通过名称、类别等方式寻找想安装的软件。值得注意的是搜索框右侧的下拉菜单,这里可以根据软件的「质量等级」(即与 YunoHost 的兼容程度)来筛选:
- 充分支持(decent):默认选中的等级,表示经测试兼容性良好,可以支持多种安装方式、自动升级、备份和恢复等等;
- 高质量(high-quality):更理想的等级,表示与 YunoHost 的兼容性较长时间以来都非常完整,而且支持 LDAP 等高级特性;
- 可运行(working):较低的等级,表示在部分方面的兼容性可能存在欠缺,但仍然基本可用。
这里,我们直接通过搜索找到 WordPress,然后点击 Install 按钮进入安装设置。
不同软件的设置内容大同小异,比较重要的几项是:
- 域名(domain):用来安装软件的域名,可以选择默认域名或者已经添加的其他域名;如本例中应选择子域名
blog.yourname.tld
; - URL 路径(URL path):用来安装软件的子路径;本例因为是安装在子域名上,此处填写
/
,即不使用子路径。 - 是否公开(expose to anonymous visitors):即是否无需登录就能查看。对于博客这种公开站点,应当保持打开;相反,如果是文件同步、系统监测等纯粹自用的服务,则应当关闭以提高安全性。
- 管理员用户(administrator user):用来管理这个 WordPress 站点的用户。YunoHost 支持 LDAP,换言之,系统有一个统一和通用的用户名录,YunoHost 中的用户也会自动成为所安装各个软件的用户(需软件本身支持 LDAP 协议),而不需像纯手动安装时那样还要单独创建用户。
(这些设置之后都可以在后台的 Applications 模块再次调整。)
完成设置后,点击下方的 Install 按钮,等待安装完成,就可以通过 blog.yourname.tld
来访问自己的 WordPress 博客了。
进阶使用
安装更多软件
除了 WordPress 之外,YunoHost 的软件目录中还有大量高质量的开源软件可供选用,有兴趣不妨自行浏览。限于篇幅,这里只结合使用经验,列举几个自己用过认为值得一试的软件。
类型 | 名称 | 说明 |
---|---|---|
网页归档 | ArchiveBox | 内置多种网页归档引擎,可以完整准确地保存大多数复杂网页以及链接的多媒体资源,支持 API 和批量操作 |
文本编辑 | HedgeDoc | 全功能在线 Markdown 编辑器,支持多人协作 |
RSS 阅读 | Miniflux | 走极简路线的阅读器,网页端几乎是纯文字,因此速度奇快,但自定义过滤、获取全文等功能一应俱全,并且可以通过 Fever API 被大多数客户端支持 |
自动化 | n8n | IFTTT 和 Zapier 的开源替代品,可以通过直观的拖拽操作组合功能模块 |
全功能云服务 | Nextcloud | 目前最完善的开源云服务方案,除支持网盘、相册、日历等基础功能,还可以安装大量第三方插件扩展功能(对硬件配置要求较高) |
文件共享 | Send | Firefox Send 的分叉版本,可以匿名方式分享大文件 |
文件同步 | Syncthing | 口碑极好的开源 Dropbox 替代品,支持局域网同步、版本控制、文件加密,有全平台客户端 |
密码管理 | Vaultwarden | Bitwarden 的开源版本,在开源密码管理方案中相对美观易用(对硬件配置要求较高) |
另外,如果你想安装的软件未被官方收录,仍然可以通过目录中两个特殊的软件,借用 YunoHost 的框架来统一管理:
- My Webapp:类似于虚拟主机(shared webhosting)的功能,安装后会为你建立一个可通过 SFTP 访问、用于存放静态文件的空间,同时可以选择创建配套的 PHP 运行环境和 MySQL 数据库。例如,你通过 Hugo 等生成器创建了一个静态网站,就可以用 My Webapp 来为其分配域名。
- Redirect:本质上是一个配置 NGINX 的懒人工具,可以选择通过 HTTP 301、302 重定向或透明的反向代理,将正在运行的本地服务映射到 YunoHost 中已添加的域名上。例如,你通过 Docker 方式安装了一些服务,就可以通过这个工具整合到 YunoHost 中。
升级和备份
自托管过程中,经常遇到的两大难题就是怎样更新软件包以及备份或还原服务器配置。这两项任务能否及时、高效地完成,很大程度上决定了自托管的体验和数据的安全性。
对此,YunoHost 都提供了较为完善的解决方案:
系统和软件更新 在后台首页点击 System update,即可同时检查系统软件包(即通过 apt 软件仓库安装的各项依赖和库)和应用程序(即通过 YunoHost 安装的各项服务)的更新,如果有更新可安装,点击相应位置的 Update 按钮即可。
备份和恢复 在后台首页点击 Backup,即可浏览或者创建服务器备份。其中,YunoHost 会在系统或软件升级时自动备份对应的文件;你也可以点击 New backup 按钮,选择特定的配置或软件创建手动备份。
点击某一个备份记录后,可以选择下载、恢复等操作。这些备份位于服务器上的 /home/yunohost.backup/archives/
路径下;如果需要跨服务器进行迁移和恢复操作,将备份文件上传到待恢复服务器的这个路径即可。
用户和权限管理
前面已经提到,YunoHost 有一套自成一体的用户和权限管理机制;这在官方文档中通过如下图示来说明(来源,中文为笔者自译):
这其中一些值得关注的特征包括:
管理员用户调整
YunoHost 不允许直接以 Linux 中的默认管理员用户 root 身份登录,而是代之以一个高权限用户 admin。据解释,这主要是出于安全、防止冲突等考虑(具体说理可见官方论坛中,维护者在我提问下的解答)。
admin 用户的权限足以运行 YunoHost 体系下的各项管理和维护功能,但不能直接修改系统文件,例如 /etc
下的各项配置文件、/var/www
下各已安装应用的源文件。如果需要修改这些文件,可以临时使用 sudo su
命令切换到 root 身份(但此时需要留意所创建和修改文件的权限)。
用户分组和权限分配
除了 admin 用户外,通过 YunoHost 后台的 Users 功能模块创建的都属于前台用户,而未登录的用户都属于访客(visitor)。
前台用户和访客的权限都可以通过 Users > Manage groups and permissions 页面进行细粒度的调节。例如:
- 你在最初安装一个服务时开启了公开访问(expose to anonymous visitors)选项,但之后希望阻止匿名用户访问,那么在 Visitors 分组中删除这个服务即可(反之亦然)。
- 你希望通过某个非管理员用户登录 SSH 或者通过 SFTP 传输文件,那么可以在 User specific permissions 中选择这个用户,然后为其赋予对应的权限。
- 你希望把 YunoHost 服务器分享给家人朋友使用,但希望限制不同类型用户访问的服务范围,那么可以点击 New group 按钮,创建几个自定义分组,然后为各个分组设置权限。
命令行管理
尽管 YunoHost 的主要卖点就在于用简明的网页前端代替了手工操作,但那毕竟不是万能的。出于配置和维护等目的,我们仍然需要不时通过 SSH 连接到服务器,直接在命令行环境下进行操作。
为此,YunoHost 提供了一个同名的命令行工具 yunohost
,其功能与网页面板大致一一对应。yunohost
命令的语法类似于 git
和 apt
,即依次由主命令、代表类别的子命令,以及具体操作和相关参数组合而成。例如:
# 安装 WordPress
yunohost app install wordpress
# 允许用户 jonedoe 访问 SSH
yunohost user permission add ssh johndoe
# 为 your.domain.tld 域名安装证书
yunohost domain cert-install your.domain.tld
更具体的用法可以用 man yunohost
或在特定子命令之后附加 --help
参数查阅。
总结和延伸讨论
尽管优点鲜明,YunoHost 也不是没有缺点。
首先,作为一个自托管服务的框架,YunoHost 的友好和易用是有边界的——仅限于它自成一体的「方法论」之内。尽管并没有明确不兼容的软件,但由于 YunoHost 会对系统的权限管理和配置方式作大量「自行其是」的调整(其中有些调整是否合理还是可以商榷的),想要跳脱出它的框架安装别的软件,往往就要费一番周折。
此外,YunoHost 底层的 Debian 是一个以稳定为第一要务的系统,软件的更新往往大幅滞后于上游,这决定了它不太适合处理服务器功能以外的日常桌面工作。
由于上述因素,如果使用 YunoHost,就要做好将一台机器完全「奉献」给它的准备;这也是 YunoHost 相比于 Docker 这类容器方案的劣势所在。
好在自托管是一个极为多元的生态,YunoHost 只是其中一个选择。如果你发现它的「方法论」并不适合自己,还可以选择 FreedomBox(Debian 内部孵化的轻量方案)、Umbrel(基于 Ubuntu 和 Docker 的方案)等各有特色的开源框架。
如果你只想托管个别服务,但又不想为此专门维护一个服务器,则可以考虑 PikaPods,这相当于一个「计件收费」的 YunoHost,并且可以灵活调整每个托管服务的硬件配置(WordPress 每月 1.6 美元起,Nextcloud 每月 3.3 美元起)。
此外,近年还涌现了大量 serverless(无服务器架构)平台,包括 Vercel、Netlify、Fly.io 等,它们往往提供了比较慷慨的免费方案,以及一键部署的能力。善用这些服务,可以低成本甚至零成本用上不少自建服务(例如,用 Netlify 部署 Hugo、用 Vercel 部署 RSSHub)。
最后,尽管自托管和开源总体而言是值得提倡的,但也不应该一股脑地把惯用的工具都换成自托管版本。
从可靠性的角度看,大多数 VPS 服务都是所谓的「无管理型」(unmanaged)服务,承诺的无宕机时间、提供的技术支持往往非常有限。因此,尽管 YunoHost 的软件目录中不乏相关解决方案,密码管理、文件同步这类事关重要数据的服务,也应该谨慎选择自托管。
尤其值得一提的是邮件服务。尽管自建邮箱听起来很酷,但更残酷的现实是,即使你做对了所有事(包括 SPF、DKIM、DMARC 等等光是读一遍名字就会昏厥的配置),从自托管服务器发出的邮件,也十有八九会进入对方的垃圾箱;只此一项,就足以抹消自建邮箱的大部分意义。
从软件质量看,尽管我们对所有无偿奉献的开源项目都应予以尊敬,但客观地说,能做到与商业服务看齐的还是少数;YunoHost 收录的很多项目都在功能和设计上存在粗糙的棱角,并不能顺畅舒心地使用。一句话,有的时候,花钱省时间并不是「人傻钱多」,反而是在权衡利弊之后的理性选择。