大学毕业之前一个冲动买了台式机,又一个冲动买了台 Linux 主机。到现在它已经运行了四年多了,简单分享下自己的玩法。

背景

毕业之前在公司附近租了房,再加上受到了网络的蛊惑,于是陷入了“买一台 NAS 来大幅提高生活质量”的念头之中。看了很多成熟的 NAS 方案(比如群辉或威联通),最后还是在高昂的价格面前望而却步。
当时的我,傻乎乎地认为品牌 NAS 的平台只是“SMB + RAID + 媒体服务器”而已,那么既然成熟的方案那么贵,为什么不搞个 Linux 自己折腾呢?脱离了平台的束缚,反而可能有更多的可能性。
最后,我决定自己买硬件搭一台 Linux 主机,做一个 HomeLab.

硬件选型

选择主机硬件的时候考虑了自己的需求,大致如下:

  1. 价格便宜:我只是个穷学生,看他们玩虚拟化的都上了 E3 E5,这么吃硬件的东西我还是不玩了吧 🌚
  2. 功耗低:24 小时开机,电费还得自己掏,所以买个 TDP 几十瓦的 i3-7100 或者 G4560 感觉好像有点烧钱。这条需求本质上可以划入上一条。
  3. 有最基本的 IO 接口:对于我来说,有 3-4 个 SATA & 千兆网口就够了。
  4. 不一定要做 RAID:硬盘容量是有限的,而备份重要的文件可以有很多方式。这条本质上还是第一条。
  5. 可以运行 Linux:我承认这条是来凑数的

英特尔® 产品规范中翻看了两周后,我的选择范围从酷睿降到了奔腾,又降到了赛扬。最后,我选择了赛扬 J3455 来做这台主机的 CPU.
配置清单如下,价格都是购买时的价格。

硬件 型号 价格(元) 备注
主板 & CPU 华擎 J3455-ITX 494
电源 金河田 480GT 99
内存 威刚 4G LPDDR3 189
SSD 22G 0 从上大学时买的超极本里拆下来的缓存盘
硬盘 2T 西数红盘 + 2T 西数蓝盘 599 + 405 贪便宜买了蓝盘
机箱 乔思伯 C2 139 2.5 寸盘位 * 1,3.5 寸盘位 * 2

后来又陆续升级了一些硬件:

硬件 型号 价格(元) 备注
电源 航嘉 300W 电源 49.9 电源风扇出了点问题导致噪音很大,于是花了几十块钱从淘宝上买了块二手电源
内存 金士顿 8G LPDDR3 379 内存嘛,多多益善
SSD 256G 紫光 S100 179 Docker 镜像太多,22G 硬盘快要装不下了
SSD 256G 闪迪 SSD Plus 219 垃圾紫光买回来以后每个月都会出问题,只好把它换掉😒
硬盘 4T 日立企业盘 880 购买于 2018 年 10 月,替换了通电很久的蓝盘

去除已淘汰的硬件,整机成本如下:

  • 硬盘(2T + 4T):1479 元
  • 主机(除硬盘以外的部分,但包括 SSD 系统盘):1469.9 元

写这篇文章的时候翻了下淘宝,发现这几年 Intel 推出了更多低功耗但性能更强的 CPU,然而这些 CPU 大多数都拿去做成了成套的 NAS、NUC 和工控机方案,貌似很难再买到 J3455-ITX 这种主板 + CPU 的组合了。

此外,由于主机的硬盘太过吵闹,有时为了享受更好的睡眠,我不得不关掉它的电源,所以我又买了一块可安安静静挂机的树莓派 4,并将一部分我认为比较重要的软件挪到了它的上面。
最近在机缘巧合之下又收了一块树莓派,不过目前处于在线但闲置的状态,跑了个 k3s 偶尔玩一玩。

附两张机器的配置图:

软件

home lab有两种玩的方向。一种是 all in one,一种是 one by one。
—— Twitter @riverscn

对于我来说,我更倾向于 one by one 的玩法。虽然我还没有那么多硬件,但一台 x86 主机,加上两块树莓派,已经足够避免主机层面的单点故障。

我的绝大部分服务都用 Docker 部署,启动脚本及配置文件全部放在一个 Git 仓库中,通过 Git 进行管理。这样以来,我就能够以极低的成本将某个服务在不同主机间迁移。
不玩虚拟化,不玩软路由,Infrastructure as Code,多机多副本,虽然可用性没有那么强,但面对日常使用还是足够了。

基础平台

上大学时上过一门计算机体系结构的课,当时装过几台 Debian 的虚拟机,这使得我对这个发行版有了一些好感。于是我选择了 Debian 作为主机的操作系统。
由于当时 SSD 空间有限,所以我选择了 Debian 的最小安装,并选用了轻量化的 LXDE 作为桌面系统(然而基本没有用过)。
除此之外,为了使用更新的软件包,我将系统更新到了 Debian testing(最新版本代号是 bookworm)。不过使用新版系统就同样需要承担不稳定的风险:较新版本的内核会偶尔出现不稳定的情况(如网络接口自动断开),所以在遇到这样的问题时就需要手动回滚到旧版内核来使用。

主机买回来还是要当 NAS 用的,所以首先安装和配置的还是 samba。通过简单的配置我们就可以在 PC 中添加网络驱动器,在局域网内访问 NAS 中的文件,还可以通过文件历史记录备份 PC 上的文件。

除了 NAS 之外,我们还需要搭建一个基础的平台用于托管各种应用,平台的组成大致如下:

  1. Docker:用于容器托管。很多流行的应用都有官方或社区维护的 Docker 镜像,使用 Docker 部署应用能够大幅降低部署成本
  2. Gogs:用于管理 Git 仓库,后来换成了 Gitea
  3. frps & frpc:服务端搭建在腾讯云上,客户端通过 Docker 部署在主机中,实现 tcp 和 http 的内网穿透
  4. 一个用来组织和管理服务脚本和配置的 Git 仓库,远端存储在 Gitea 中
  5. 一些用于日常操作的基础工具,如 git, vim 和 tmux

有了这些组件,我就可以非常快捷地部署新的服务。

应用软件

在主机和树莓派上部署的应用可以称得上五花八门,绝大部分都是通过 Web UI 进行交互,使用 Docker 进行托管,通过 volume 完成目录共享。一部分不太适合使用 Docker 托管的服务(如需要使用 ssh 的 Gitea),早期我选择使用 Supervisor 托管,后来全部迁移到了 systemd 上。

部署方式大同小异,而且大部分部署在 Docker 上的应用都能够做到开箱即用,所以没有什么可以单独分享的。简单列举一下我在家部署的应用:

软件 简介 托管方式
Caddy 配置简单的 HTTP 服务器,用做主机网关 docker
acme.sh 获取 Lets’Encrypt 的 HTTPS 证书,用于内网和外网的 HTTPS 访问 cron
Cockpit 主机监控面板 systemd
Portainer 容器管理工具 docker
Prometheus & AlertManager & Grafana 监控报警套件,偶尔用于主机问题排查 docker
Node Exporter & cAdvisor prometheus exporter docker
Loki & promtail 日志收集平台及组件,负责聚合主机、容器和网关请求日志 docker
Drone & Drone Runner CI 平台,搭配 Gitea 使用 docker
Clash 代理服务器 docker
yacd clash 管理面板 caddy 静态托管
aria2 下载工具,支持 HTTP、BT 和磁力链接 docker
AriaNg aria2 管理面板 caddy 静态托管
Sync Home 专有软件,P2P 文件分享,也可用于文件同步 docker
Kiwix 离线的维基百科服务,以备不时之需 docker
NextCloud 网盘服务,从某种意义上可以代替百度网盘 docker
WebDAV WebDAV 服务,托管 Joplin 中的笔记内容 docker
Tiny Tiny RSS RSS 阅读器,用于替代 Feedly docker,有人专门做了容器化部署方案
rss-proxy 一个极为简陋的 HTTP 反向代理,方便 TT-RSS 抓取资源 docker
fava & beanbot Beancount UI 和 Telegram bot,详见《开始使用 Beancount》 systemd
snapdrop 基于 WebRTC 的本地网络文件传输工具 docker

网络

服务部署可以通过 docker 轻松搞定,然而绝大部分服务都是通过 Web UI 进行交互的,所以我们还需要找到一个快捷的方案来从内网或外网访问这些服务。

HTTP

处理 DNS 解析时,为了访问方便,我在内网中通过 dnsmasq 代理了顶级域名 s. 的解析请求:将 *.s 的域名全部解析到主机的固定 IP,针对某些希望暴露到公网的服务,我会将 *.stdioa.com 的域名解析到很久很久以前买的腾讯云学生机上。
针对 HTTP(S) 的路由,我在内网中使用 Caddy 作为网关;公网中我使用了 Nginx 作为网关,然后使用 frp 将公网的请求导入到内网中,再通过内网主机上的 Caddy 网关进行路由。

请求拓扑结构大致如下:

这样,Web 访问的问题就解决了,但偶尔还会有一些特殊的情况发生。

SSH

在外偶尔会有一些针对 NAS 或树莓派的运维需求,或者可能只是连到树莓派上去编辑一下 beancount 的交易记录,此时就需要通过 SSH 来连接到主机,通过 shell 来进行操作。

此时我同样用到了 frp:建立一个 TCP 代理,将 NAS 的 22 端口映射到腾讯云上的某端口,即可通过 SSH 来连接这个端口。

在外访问内网服务

出于安全考虑,我不会把涉及到隐私的服务(比如 Fava)暴露在公网上。但有时还是要访问一些不想暴露到公网的服务,或临时搭建的服务,所以需要想办法访问到内网主机的端口。

此时至少有三种端口映射方案:

或者,我们还可以配置 VPN 作为终极解决方案。
写这篇文章时,我恰好接触到了 tailscale. 它是一个安全的虚拟组网产品,而且配置十分简单,只需要十分钟即可将终端设备直接接入内网。因此,如果需要高频访问内网服务的话,可以考虑直接使用 tailscale 来完成。
不过需要注意的是:tailscale 是一个商业产品。如果你对自己的数据安全十分担忧,可以考虑使用 nebula 这样的自建组网方案作为替代。

数据备份

俗话说:“备份不做,十恶不赦”。但不得不承认我的经济实力和盘位都十分有限,没有办法做 RAID,所以只好选择性地备份某些比较重要的数据,如 Gitea Repo,WebDAV 中的笔记内容,以及 PC 内的文件等。

热备份的手段比较简陋:

  1. PC 中的文件直接使用“文件历史记录”功能,通过 SMB 协议备份到 NAS 中;
  2. 通过 systemd Timer 定时触发脚本,用 rsync 将本机或腾讯云上的数据增量同步到备份位置。

对于冷备份,我使用了 Cobian Backup 来定期将数据备份到一块离线硬盘。

如今

这台主机玩到现在,我觉得它已经不是一台 NAS 了,而是更像一个 HomeLab.
对于我来说,HomeLab 是一个可以让人快速实现某个想法或需求的平台。有了 Linux 和 Docker,面对日常生活中某些天马行空的需求时,我可以快速实现、快速部署。在享受 HomeLab 给我带来便利的同时,我还可以享受折腾它带来的奇怪的成就感。

举个例子,三月份的时候玩塞尔达发现了一个旷野之息的地图网站,然而由于网站的 CDN 带宽极为有限,导致这个服务的性能奇差,加载一张图片可能需要十几秒到一分钟的时间。于是我在某个晚上花了不到一个小时写个惰性的本地缓存服务,并将它部署在了内网中。此后,当我需要在海拉鲁大陆的角落寻找宝藏时,就可以享受到地图秒开的快感。

除此之外,HomeLab 的另一大价值在于它让我们拥有了数据和功能的所有权
现代互联网的商业魔爪已经伸向了每个用户,几乎所有的互联网服务都需要以金钱和/或隐私作为代价来换取使用权。如果美好的万维网早已不在,我们的力量也无法支撑我们颠覆商业规则,那我们是否有可能在互联网中搭建一个只属于自己或一小撮人的庇护所呢?
对于我来说,通过 HomeLab 自建一些服务(如 Tiny Tiny RSS 或 BitWarden),将云服务私有化,让个人隐私留在自己的硬盘之中,可能是最好的解决方案了。

最后,我想为大家推荐 awesome-selfhosted ,大家可以在这里查找并选择合适的自建服务。

相关阅读