# 自托管

## 概念

### 自托管

引用自 [Wikipedia](https://en.wikipedia.org/wiki/Self-hosting_(web_services))：

> 自托管 (self-hosting) 是使用私人网络服务器运行和维护网站或服务的做法，而不是使用某人自己控制之外的服务。自托管使用户可以更好地控制自己的数据、隐私和计算基础设施，并有可能节省成本并提高技能。

服务或内容通常通过自己的硬件在本地提供。通常，“自托管者”通过家庭互联网连接使用较旧的企业级硬件，但他们也使用其他托管提供商的硬件。这仍然被认为是自托管。**本篇由于不关注硬件配置和网络环境故不做特殊区分，不会过度强调硬件挑选、网络拓扑等内容。**

### <span data-immersive-translate-paragraph="1" data-immersive-translate-walked="23e37ad1-6097-4744-a1f2-323920b6e1b6"><span class="notranslate immersive-translate-target-wrapper" data-immersive-translate-translation-element-mark="1" lang="zh-CN"><span class="notranslate immersive-translate-target-translation-theme-none immersive-translate-target-translation-inline-wrapper-theme-none immersive-translate-target-translation-inline-wrapper" data-immersive-translate-translation-element-mark="1"><span class="notranslate immersive-translate-target-inner immersive-translate-target-translation-theme-none-inner" data-immersive-translate-translation-element-mark="1">其它</span></span></span></span>

<span data-immersive-translate-paragraph="1" data-immersive-translate-walked="23e37ad1-6097-4744-a1f2-323920b6e1b6"><span class="notranslate immersive-translate-target-wrapper" data-immersive-translate-translation-element-mark="1" lang="zh-CN"><span class="notranslate immersive-translate-target-translation-theme-none immersive-translate-target-translation-inline-wrapper-theme-none immersive-translate-target-translation-inline-wrapper" data-immersive-translate-translation-element-mark="1"><span class="notranslate immersive-translate-target-inner immersive-translate-target-translation-theme-none-inner" data-immersive-translate-translation-element-mark="1">推荐阅读：[与自托管相关的常用术语和概念的解释和定义 --- Explanations and Definitions for Common Terms and Concepts Related to Self-Hosting (r-selfhosted.com)](https://wiki.r-selfhosted.com/learn/common-terms-and-concepts/)</span></span></span></span>

## 缘由

为什么要自托管，当然离不开本书的主题：隐私

假如你想要使用一个和个人信息相关的服务，且如果这个服务不具有以下特征的话：

- 本地优先（应用可以脱机工作）
- 端对端加密（E2EE）

那么很遗憾，你的个人信息肯定会以明文形式经过他人实现的服务（你无法掌控）处理，这就意味着你的隐私可能会受到侵犯，你的数据可能会被用于盈利。或者更危言耸听一些，即使使用的服务基于他人运行的自由软件与适当的隐私策略，其本质依旧是[服务代替软件](https://www.gnu.org/philosophy/who-does-that-server-really-serve.html)，用户定然会失去一定的自由。

自托管可以让你拥有真正的数据主权。通过自托管，你可以选择在自己能够掌控的设备上存储和处理数据，而不需要依赖第三方服务。这意味着你的个人信息决不会经过他人掌控的服务器，不会轻易地被未经授权的人访问。<span data-immersive-translate-paragraph="1" data-immersive-translate-walked="23e37ad1-6097-4744-a1f2-323920b6e1b6"><span class="notranslate immersive-translate-target-wrapper" data-immersive-translate-translation-element-mark="1" lang="zh-CN"><span class="notranslate immersive-translate-target-translation-theme-none immersive-translate-target-translation-inline-wrapper-theme-none immersive-translate-target-translation-inline-wrapper" data-immersive-translate-translation-element-mark="1"><span class="notranslate immersive-translate-target-inner immersive-translate-target-translation-theme-none-inner" data-immersive-translate-translation-element-mark="1">推荐阅读：《</span></span></span></span>[自托管宣言](https://wiki.qunn.eu/books/b1d10/page/ef575 "自托管宣言")》

如果觉得学习、搭建、维护应用及服务的成本过高（例如投入时间与金钱）无法接受，你应该转至《[公益服务站点索引](https://wiki.qunn.eu/books/1534b "公益服务站点索引")》，寻找合适的服务站点，并确保自己的个人信息能在此站点上得到足够的保护。

## 做法

### 准备

#### 命令行操作及 shell 环境配置

<p class="callout info">如果选用了合适的编排工具（后面提及），可省去此步</p>

建议大致掌握以下的知识点：

- 基本的命令行操作 
    - SSH 登入
    - Bash（或其它 Shell）
    - GNU Readline（可选，多用于 Shell 与 CLI 工具）
    - man（即手册 manual，**RTFM**）
    - 编辑器（GNU nano/Vim/...）
- GNU/Linux, BSD 规范、标准及知识 
    - 操作系统基本知识（大学计算机基础？）
    - FHS（文件系统层次化标准）
    - 所选发行版对应的软件包管理器、打包格式规范（可选）

参考链接：

- [南京大学的《操作系统》课程](https://jyywiki.cn/)
- [计算机教育中缺失的一课 · the missing semester of your cs education (missing-semester-cn.github.io)](https://missing-semester-cn.github.io/)

#### 计算机网络及云服务商

建议大致掌握以下的知识点：

- 计算机网络基础（可选）
- [网站主机知识](https://www.w3school.com.cn/hosting/index.asp)

购买域名时，推荐使用以下网站做域名比价（无利益相关）：

- [Compare Prices of All Top-Level Domains | TLD-List](https://tld-list.com/)
- [WHO.CX](https://who.cx/)

免费域名大多数都是二级域名，建议付费购买顶级域名，毕竟免费的才是最贵的。

购买服务器时，建议考虑自己的使用需求，选择合适的云服务商（检查它们的 ToS/服务条款，SLA/服务等级协议，成立年份，客户支持，工作时间，隐私政策，用户评价等）。同样，不要贪小便宜~

### 简化

如果想要跳过学习、配置环节，则可以考虑下方给出的方案快速自托管应用

#### PaaS（平台即服务）

严格意义上来说不算是自托管，PaaS 主要面向开发人员和程序员，部署方式与平台由开发者决定

<p class="callout danger">注意：使用 PaaS 意味着依赖第三方服务，会影响所部署服务的安全性与扩展性</p>

#### 软件包

<p class="callout info">基于软件包的部署方式</p>

大多数 GNU/Linux 或 BSD 发行版的软件仓库中都含有丰富的可用于自托管的软件包，这时使用系统提供的软件包管理器便可以轻松部署你想要搭建的服务（例如：IRC/XMPP 服务端等）。如果软件仓库中缺少所需的软件包，可能需要阅读项目中提供的文档以进行安装，有下面几种可能：

1. 使用第三方软件源
2. 容器镜像（Docker）
3. 手动安装（例如：单二进制文件+配置文件+服务文件）
4. ...

当然，如果对命令行操作不够熟悉、想要快速入手或者偏好使用图形化界面进行自托管，可以尝试下面列出的项目

##### 相关部署项目

<p class="callout danger">注意：虽然以下项目均为自由软件，但其中维护的软件包或脚本可能有一定的局限性（例如无法自定义配置或及时更新）</p>

- [FreedomBox](https://www.freedombox.org/)

> FreedomBox 是基于 Debian 的自由软件家庭服务器操作系统，由 FreedomBox 基金会支持。FreedomBox 于 2010 年推出，现已从一个软件系统发展成为一个生态系统，包括一个 DIY 社区和一些商业产品

引用自 [Wikipedia](https://en.wikipedia.org/wiki/FreedomBox)

可以在 Debian 发行版上直接安装，**且 Freedombox 仅依赖 Debian 软件包，**故支持应用较少。[Debian Wiki 上也有相关文档](https://wiki.debian.org/FreedomBox)

- [YunoHost](https://yunohost.org/)

> YunoHost 是基于 Debian GNU/Linux 的发行版，由自由软件组成，旨在为广义上的自托管提供便利。

引用自 [Wikipedia](https://fr.wikipedia.org/wiki/YunoHost)

需使用第三方软件源进行安装，且有自己的打包格式（包含了安装、更新、备份、卸载等脚本）

推荐阅读：[像装应用一样轻松自建服务：YunoHost 使用指南](https://client.sspai.com/prime/story/yunohost-tutorial)

- [Sandstorm](https://sandstorm.org/)
- 参考 [Self-hosting Solutions - awesome-selfhosted](https://awesome-selfhosted.net/tags/self-hosting-solutions.html) 中未带有 Docker 标签的项目

#### 容器化

<p class="callout info">基于容器化（Docker/Podman）的部署方式</p>

区别于上述的裸机（bare metal）部署，容器化部署类似于在机器上使用虚拟机，但性能开销更小、专注于项目本身（仅关注容器内1号进程及其子进程），对比裸机部署更具有可移植性、便捷性与隔离性。同时很多项目也会提供容器部署的文档与镜像，所以目前来看容器化部署方式有很高的流行度。但也有一些情境不适合使用容器化部署：

1. 应用足够简单以至于不需要容器化（例如：静态网页、单二进制应用等）
2. 应用对性能有很高要求（例如：大量的 IO 操作）
3. ...

同时，容器编排方式也是各式各样：命令行运行、基于 YAML 配置编排、抑或是使用后面提及的 IaC 工具组织，具体可以根据个人需求进行选择。比如说应用无需过多配置开箱即用，则可以直接使用命令行运行；应用需要使用数据库、Web 服务器等服务则可以使用 Compose 文件编排；如此云云

##### 集群部署

集群部署（Docker Swarm/K8s/K3s）暂不提及，因为可能超出了自托管的需求。想要了解的话可以查阅下列网站：

1. [Docker Swarm Rocks](https://dockerswarm.rocks/)
2. [K3S Rocks](https://k3s.rocks/)

##### 相关项目

参考 [Self-hosting Solutions - awesome-selfhosted](https://awesome-selfhosted.net/tags/self-hosting-solutions.html) 中带有 Docker 标签的项目

<p class="callout warning">接下来是 [laC](https://en.wikipedia.org/wiki/Infrastructure_as_code)（基础设施即代码）的方案，需要学习如何配置项目与编排，请考虑这是否值得（over-engineered）</p>

#### Ansible

[Ansible (software) - Wikipedia](https://en.wikipedia.org/wiki/Ansible_(software))

一言以蔽之：基于 YAML 编写的 Shell scripts，但是支持批量远程执行、使用简单灵活、社区资源丰富，还支持图形化界面（第三方应用）

##### 相关项目

- [Self-hosting Solutions - awesome-selfhosted](https://awesome-selfhosted.net/tags/self-hosting-solutions.html) 中带有 Ansible 标签的项目
- [HomelabOS](https://homelabos.com/) 用 Ansible 部署 Docker
- [DebOps - Your Debian-based data center in a box](https://debops.org/)
- Code Forges (GitHub/GitLab/Codeberg/...) 中有很多分享 Ansible Playbooks/Roles 的代码库，建议搜索 infrastructure，语言筛选 Jinja

#### NixOS/GNU Guix

俺没用过，希望有人分享一下使用经验与技巧

##### 相关项目

Code Forges (GitHub/GitLab/Codeberg/...) 中有很多分享 NixOS/GNU Guix 配置的代码库，建议搜索 infrastructure，语言筛选 Nix/Scheme

#### 不推荐

##### 服务器运维管理面板

如果你无法接受长时间在命令行上操作，可以尝试这些面板，但有很多理由不去使用它们：

- 不透明，不自由，不安全（扩大了攻击面）
- 占用过多服务器资源
- 面向的用户群体不是自托管者（建站/从业人员）
- 大多数面板由中国企业开发，有上报数据的嫌疑（no opt-out）

##### 一键脚本

一般来说，一键脚本=项目开发者自己编写的 shell script。虽然安装简单，但是不适合后续的配置修改、更新备份等操作。所有的应用应尽可能统一使用同一个编排工具进行搭建与维护。

### 进阶

下面将介绍一些能利于自托管服务后期使用/维护的方法

#### 监控

为什么要监控：提高服务质量、降低维护成本

要监控什么：服务器本身、服务健康状况

怎么监控：Zabbix/Grafana/Uptime-kuma

#### 更新

及时跟进上游版本，可以减少安全风险，增加更多特性

##### 软件包

<p class="callout danger">尽量避免使用</p>

deb-based: [UnattendedUpgrades](https://wiki.debian.org/UnattendedUpgrades)

rpm-based: [DNF Automatic](https://dnf.readthedocs.io/en/latest/automatic.html)

Arch: just no

##### Docker

<p class="callout info">Podman 有 [auto-update](https://docs.podman.io/en/latest/markdown/podman-auto-update.1.html)</p>

[Watchtower - A container-based solution for automating Docker container base image updates.](https://containrrr.dev/watchtower/)

[Diun - Receive notifications when an image is updated on a Docker registry](https://crazymax.dev/diun/)

[mag37/dockcheck: CLI tool to automate docker image updates. No pre-pull, selective, notify, prune. (github.com)](https://github.com/mag37/dockcheck)

##### 自定义

crontab + shell scripts or whatever

#### 备份

及时备份关键数据，可以减少意外损失，方便恢复服务

##### 策略

全盘备份：常见于服务商的快照功能

特定路径备份：仅备份关键数据

还有什么 3-2-1 原则 4-3-2-1 原则

##### 封装（wrapper）

[backupninja](https://0xacab.org/liberate/backupninja)

[offen/docker-volume-backup: Backup Docker volumes locally or to any S3, WebDAV, Azure Blob Storage, Dropbox or SSH compatible storage (github.com)](https://github.com/offen/docker-volume-backup)

#### 鉴权

可选，减少额外注册/登录流程，集中化认证授权

##### 协议

- 本地
- SSO 
    - LDAP
    - SAML
    - OAuth
    - OpenID
    - ...

##### 应用

- [authentik](https://goauthentik.io/)
- [Authelia](https://www.authelia.com/)
- [Keycloak](https://www.keycloak.org/)
- ...

## 参考

### Wiki

#### [r/SelfHosted Wiki](https://wiki.r-selfhosted.com/)

#### [r/homelab Wiki](https://libreddit.qunn.eu/r/homelab/wiki/)

#### [The Homelab Wiki](https://thehomelab.wiki/)

### 列表

#### [awesome-selfhosted](https://awesome-selfhosted.net/)

庞大的自托管项目列表

#### [selfhosted-music-overview](https://github.com/basings/selfhosted-music-overview)

聚焦于自托管音乐服务端和客户端

#### [Free and Open Source Photo Libraries](https://github.com/meichthys/foss_photo_libraries)

聚焦于自托管图库服务端和客户端

#### [Free and Open Source Note Taking Applications](https://github.com/meichthys/foss_note_apps)

聚焦于自托管笔记服务端和客户端

### 教程

#### [LandChad.net](https://landchad.net/)

[Luke Smith](https://lukesmith.xyz/) 发起的项目

#### [Comfy.Guide](https://comfy.guide/)

[Denshi](https://denshi.org/) 发起的项目

#### [Thomas Nagy / Freedom fighters · GitLab](https://gitlab.com/bkil/freedom-fighters)

[secuchart](https://gitlab.com/bkil/secuchart) 维护者发起的项目

### 博/播客

#### [selfh.st - Self-hosted content and software](https://selfh.st/)

周刊，每周五更新

其提供的调查问卷非常值得参考：[2023 Self-Host User Survey Results (selfh.st)](https://selfh.st/survey/2023-results/)

#### [老苏的blog](https://laosu.tech/)

文章主要与群晖和 Docker 相关，可以视作自托管项目推荐

### 社区

#### Reddit

- [r/selfhosted](https://reddit.com/r/selfhosted)
- [r/homelab](https://reddit.com/r/homelab)

#### Lemmy

- [!selfhost@lemmy.ml](https://lemmy.ml/c/selfhost)
- [!selfhosted@lemmy.world](https://lemmy.world/c/selfhosted)

#### PieFed

[~selfhost@piefed.social](https://piefed.social/f/selfhost)