组了一台 NAS

我最近组了一台 NAS,用于同步手机上的相册、自建云盘存储文件、同步 Obsidian 的笔记、存储和管理影音资源、搭建 Git 托管代码等。这篇文章记录我是怎么做的。

硬件

主板选用云星 CS246,一款专门面向 NAS 的 ITX 小主板。它有 LGA 1151 CPU 插槽、2 个 2.5G 网卡(可加钱升级成 4 个)、8 个 SATA 3.0 接口、两个 NVMe 插槽,很适合用来做 NAS。花费¥429。

CPU 买了个 i3 9100T 二手散片。4 核 4 线程,带核显,可以硬解码,做 NAS 基本够用;TDP 35w,比较省电。花费¥135。

内存条选用七彩虹 DDR4 2666 8GB。说实话 8G 有点小,但是考虑到我的腾讯云服务器内存才 1G,苦日子过惯了,8G 凑合着也能用。花费¥119。

固态硬盘也是七彩虹的,CN600 128GB。Linux 系统盘 64G 都绰绰有余了,不过现在能买到的 NVMe 硬盘最小也有 128G。花费¥115。

机箱选的是疾风知 N52 NAS 机箱。它有 5 个盘位,硬盘仓支持安装风扇给硬盘散热。选它是因为我觉得它比较好看,而且相对便宜。花费¥229。

电源选了个 TT TRM SFX 350W。花费¥159。

散热器选了个铜芯铝鳍片的下压式散热器,花费¥27。硬盘仓风扇买的是利民的 12CM 无光静音风扇¥17。

总共花费¥1230。算下来,似乎并不是很划算😂。但自组 NAS 图的就是 DIY 的乐趣,为的是自由定制的权力,便不计较这个了。

系统

系统安装的是 Ubuntu 24.04.3 LTS。我理解的 NAS 就是一台 Linux 服务器,需要什么服务就在上面装就好了,这样最能自由定制,因此没有选择飞牛之类的 NAS 专用系统。主板装好后,插入安装 U 盘试下能否点亮。成功点亮后,顺便也把系统装好了。

硬盘

我本想用两块硬盘组一个 RAID 1,但是现在机械硬盘涨价严重,就只买一块 4 TB 的西数红盘。反正一块硬盘一时半会儿坏不了,等后面硬盘降价了(希望),再组成 RAID 1。

为了后续扩展成 RAID 1,我把这块 4 TB 的硬盘组成一个单盘的 RAID 1。首先使用 parted 创建分区,执行 sudo parted /dev/sda 进入 parted 交互界面,然后依次执行

1
2
3
4
(parted) mklabel gpt                # 创建分区表
(parted) mkpart primary 0% 100% # 创建主分区
(parted) print # 打印查看下分区表
(parted) set 1 raid on # 标记为 raid 分区

然后使用 mdadm 创建 raid:

1
2
sudo mdadm --verbose --create /dev/md0 --level=1 --raid-devices=1 --force /dev/sda1
sudo mkfs.ext4 /dev/md0

然后挂载到 /data

1
2
3
4
5
6
sudo mkdir /data
sudo mount /dev/md0 /data

# 挂载持久化
sudo blkid | grep /dev/md0 # 查看一下 UUID
echo UUID=ae65b749-4e1e-4209-ae57-15ec83578c5c /data ext4 defaults 0 0 | sudo tee -a /etc/fstab # 配置写入 /etc/fstab

Mdadm 的配置最好也持久化一下:

1
2
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
sudo update-initramfs -u

以后如果要加硬盘,可以执行以下命令即可:

1
sudo mdadm --grow /dev/md0 --raid-devices=2 --add /dev/sdb1

网络环境

我对网络环境有几点要求。第一,不能只在内网访问,在外面也要能访问。第二,要用域名访问,用不同的域名区分不同的服务,而不是用 IP + 端口。第三,同一个服务在内网和外网的访问地址是一样的,这样回到家后不需要修改任何配置。

Tailscale 实现内网穿透

为了实现内网穿透,我的方案是使用 Tailscale。Tailscale 是一个基于 WireGuard 实现的 VPN,通过 UDP 打洞实现内网穿透。如果打洞成功,则可以直连通信,无需经由中继服务器;通信速度取决于带宽,非常方便。

Tailscale 非常容易使用。在机器上安装好 Tailscale 后,执行 tailscale up,访问链接登录账号,即可将当前主机加入这个账号下的 Tailscale 网络 (Tailnet)。

1
2
3
4
5
$ sudo tailscale up

To authenticate, visit:

https://login.tailscale.com/a/******

同时手机上也安装 Tailscale 客户端,登录账号后,也可以加入我的 tailnet。这样手机和 NAS 便可以随时通信。

NAT 打洞也不是总能成功。根据 Tailscale 官方文档,如果通信双方都在 Hard NAT 中,则不能实现直连。就需要通过中继服务器(称为 DERP),速度很慢。

Client A NAT Type Client B NAT Type Expected Connection
No NAT No NAT Direct
No NAT Easy NAT Direct
No NAT Hard NAT Direct
Easy NAT Easy NAT Direct
Easy NAT Hard NAT Relayed
Hard NAT Hard NAT Relayed

好在现在宽带基本上都提供 ipv6 公网地址。我在光猫上开启允许内网设备使用 ipv6 通信,让 NAS 拥有公网 ipv6 地址。这样,使用 4G/5G 网络能 100% 直连;在外面连的 WIFI 如果支持 ipv6,也能直连。

配置 DNS 服务器

我的目标是在家里连上家里的 WiFi,或者在外连上 VPN,都可以用同样的域名访问 NAS 上的服务。这首先要在 NAS 上部署一个 DNS 服务器。我使用的是 CoreDNS,它的配置非常简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.:53 {
bind 192.168.1.2
hosts {
192.168.1.2 nas.luyuhuang.tech
192.168.1.2 immich.luyuhuang.tech

ttl 60
reload 1m
fallthrough
}

forward . /etc/resolv.conf
cache 120
reload 6s
errors
}

这样的配置让 CoreDNS 监听 192.168.1.2:58,在 hosts 中配置域名解析规则。其他域名默认 forward 到系统 DNS 解析。在路由器中将 NAS 的 IP 地址固定为 192.168.1.2,并将首选 DNS 服务器设置为 192.168.1.2。这样任何通过我家路由器上网的设备都可以通过域名访问 NAS 上的服务。

为了让连上 VPN 的设备也能用同样的域名访问 NAS,我们在 Tailscale 的控制台设置一个 Split DNS,地址设置为 NAS 的虚拟 IP;并指定后缀为 luyuhuang.tech 的域名请求 NAS 上的 DNS 服务器。

由于 NAS 的虚拟 IP 和物理局域网的 IP 不同,所以还要让 CoreDNS 监听虚拟 IP,解析结果也要返回虚拟 IP。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.:53 {
bind 100.64.0.3
hosts {
100.64.0.3 nas.luyuhuang.tech
100.64.0.3 immich.luyuhuang.tech

ttl 60
reload 1m
fallthrough
}

forward . /etc/resolv.conf
cache 120
reload 6s
errors
}

这样,例如同样是访问 nas.luyuhuang.tech,内网设备解析得到 192.168.1.2,连上 VPN 的设备则得到虚拟 IP 100.64.0.3。它们都可以用同样的域名访问 NAS。

配置 Nginx 和 HTTPS

我是用 Nginx 作为所有服务的反向代理,这样可以统一使用 80 或 443 端口,但使用不同的域名区分不同的服务。为了简单我直接使用 Docker 版的 Nginx,简单写个 docker-compose.yaml 即可。因为要反向代理到各种服务,网络模式使用 host 模式。

1
2
3
4
5
6
7
8
9
services:
nginx:
image: nginx
container_name: nginx
network_mode: host
volumes:
- ./config:/etc/nginx
- ./cert:/cert
restart: unless-stopped

我的域名 luyuhuang.tech 申请了 Let’s Encrypt 的证书,因此可以直接使用这个证书部署 HTTPS 服务。简单写个脚本同步证书到 NAS 上,这样也不用担心证书过期。

这样服务配置起来就很简单了。例如我的 Homepage 服务(下文会介绍)监听 http://127.0.0.1:4000,Nginx 这边就直接反代过去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 80;
server_name nas.luyuhuang.tech;

location / {
return 301 https://nas.luyuhuang.tech$request_uri;
}
}

server {
listen 443 ssl;
server_name nas.luyuhuang.tech;

include /etc/nginx/ssl.conf;

location / {
proxy_pass http://127.0.0.1:4000;
proxy_set_header Host nas.luyuhuang.tech;
}
}

安装各种服务

这里介绍几个我的 NAS 上安装的服务。这些服务都是用 Docker 安装的,安装步骤都很简单,这里就不介绍了。

Immich

Immich 是一个自建相册服务。它自带 Android 和 iOS 手机客户端,可以将手机的相册同步到 NAS 上。实际上我这次搞 NAS 的导火索就是我的小米云相册的容量满了。它支持 AI 人脸识别、以文搜图的功能(需要 GPU 支持);支持地图足迹功能。我用下来体验还是很不错的。

Cloudreve

Cloudreve 是自建网盘服务。它的网页端功能很不错,大多数格式的文件,无论是图片、音乐、视频,还是文档、压缩包,都可以直接在网页端打开。它支持 WebDAV,我用来作为笔记软件的同步服务;支持离线下载,我用来下载影音资源。它还支持各种云服务的对象存储,不过我暂时还没用到。缺点是没有 Android 客户端,iOS 客户端则需收费。

qBittorrent

qBittorrent 不用介绍了吧,著名的 Bittorrent 下载器。它可以与 Cloudreve 联动,作为 Cloudreve 的离线下载器。在 Cloudreve 中创建离线下载任务,调用 qBittorrent 下载,下载完成自动存入 Cloudreve 网盘。

Jellyfin

Jellyfin 是一个影视资源库。它将影视资源整理成影片和剧集,并从影视数据库中拉取海报、标题、介绍等元数据,方便观看。它能保存观看进度,并支持服务器解码(硬解码需要 GPU 支持),方便在各种设备中观看。除了网页端和 PC 客户端,它还支持手机客户端和 TV 客户端。

我让 Jellyfin 通过 WebDAV 挂载 Cloudreve,使用其中的影视资源。Jellyfin 本身不支持远程挂载,我使用 Rclone 的 Docker 插件,让 Docker 将 WebDAV 链接挂载成 Jellyfin 所在容器的 volume。

1
2
3
4
5
6
7
volumes:
cloudreve:
driver: rclone
driver_opts:
remote: 'cloudreve:'
read_only: 'true'
dir_cache_time: '1s'

Homepage

最后我还部署了 Homepage,将 NAS 上所有的服务都集中到一个主页,顺便还能显示机器的基本状态、各个服务的运行状态。


组了一台 NAS
https://luyuhuang.tech/2026/01/08/diy-nas.html
Author
Luyu Huang
Posted on
January 8, 2026
Licensed under