NAS 自托管完全指南

折腾 NAS 自托管大半年了,踩了不少坑。这篇把硬件选型、服务部署、网络配置到日常运维的经验都记录下来,给同样想自建家庭服务器的朋友一个参考。不是教程,是踩坑笔记。

硬件

机器是绿联 DH4300 PLUS,aarch64(ARM64)架构,8GB 内存。选它主要是性价比——千元出头,四个盘位,ARM 架构功耗低,跑 Docker 绰绰有余。如果你要跑 x86 才有的镜像或者虚拟机,那得换 N100 小主机之类的方案;但纯做容器化服务,ARM 完全够用。

项目配置
型号绿联 DH4300 PLUS
架构aarch64 (ARM64)
内存8GB DDR4
盘位4 × 3.5" HDD

SSH 连接

SSH 地址 home@192.168.1.2,建议第一件事就是把自己加入 docker 用户组,这样后面所有 docker 命令都不用加 sudo

sudo usermod -aG docker home

加完重新登录才会生效(不是重启,是退出 SSH 再连一次)。

跑的服务一览

踩坑实录

坑一:NAS 上没有 git

绿联的系统是个精简 Linux,默认没装 git。想传代码或配置文件上去,最靠谱的方式是 SFTP而不是 SCP——SFTP 支持断点续传,大文件比 SCP 稳得多。Mac 上直接 Finder → 前往 → 连接服务器,输入 sftp://home@192.168.1.2 就能图形化管理文件。

坑二:内联 SSH 频繁超时

如果你的脚本里有大量内联 SSH 命令(一条一条 ssh home@... "cmd" 这么跑),会发现经常 60-150 秒才响应,甚至直接超时。原因是每次 SSH 都要重新建立连接、握手、认证,NAS 的 SSH 守护进程扛不住高频请求。

解决方案:把脚本写到本地,一次性传过去执行

# 不要这样(每条命令一个 SSH 连接):
ssh home@192.168.1.2 "docker ps"
ssh home@192.168.1.2 "docker logs xxx"

# 要这样(一次连接,批量执行):
cat deploy.sh | ssh home@192.168.1.2 "sh -s"

sh -s 表示从标准输入读取脚本。这样只建立一次连接,所有命令在远端连续执行,速度和稳定性都好得多。

坑三:SSH 密码交互

Mac 上没有 sshpass(brew 安装也被移出了主仓库),自动输密码得用 expect

#!/usr/bin/expect -f
set timeout 30
spawn ssh home@192.168.1.2 "docker ps"
expect "password:"
send "nas.home.@X94\r"
interact

更推荐的做法还是配 SSH 密钥免密登录,ssh-copy-id home@192.168.1.2 一步到位,之后再也不用输密码。

坑四:Docker bind mount 不会热加载

这是新手最容易栽的坑。Docker 的 bind mount(挂载宿主目录)是只读快照式的——你在宿主上改了挂载目录里的文件,容器内不会自动看到变化,必须重启容器:

# 改完配置文件后:
docker restart <container_name>

# 或者如果用的是 docker-compose:
docker-compose restart <service_name>

volume(命名卷)和 bind mount 行为不同,但大部分自托管场景用的都是 bind mount(因为要直接编辑宿主上的文件)。记住一条:改了挂载内容,就 restart

坑五:端口避让

NAS 系统自带的服务会占用常见端口。比如 PostgreSQL 默认 5432、Redis 默认 6379,如果你直接用默认端口起 Docker 容器,会跟宿主上的实例冲突。我的做法是统一偏移 +500

这样一眼就能看出是什么服务,也不会跟任何默认端口撞车。

Portainer:比命令行更靠谱

说实话,在 NAS 这种 ARM 架构 + 精简系统上,命令行操作 docker-compose 偶尔会遇到编码问题、换行符问题、终端宽度截断问题。装了 Portainer 之后,大部分日常操作(起停容器、看日志、进 shell、更新镜像)都在网页上完成,体验明显比命令行顺畅。

部署很简单:

docker run -d -p 9443:9443 \
  --name portainer \
  --restart=always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:latest

网络:镜像拉取失败

NAS 在国内网络环境下拉 Docker Hub 镜像经常会失败或极慢。两个办法:

  1. 配置 Docker 代理:在 /etc/docker/daemon.json 里加镜像加速地址(阿里云、DaoCloud 等都有免费加速服务)
  2. 本地拉取再传:在 Mac 上 docker pull + docker save 导出 tar,SFTP 传到 NAS,再 docker load

方法二虽然土但百分百可靠,适合部署 ARM 架构专用镜像时使用。

写在最后

NAS 自托管的乐趣在于:你拥有对数据的完全控制。Gitea 里存的是你自己的代码,PostgreSQL 里跑的是你自己的数据库,没有哪天服务商会突然关停。代价是你得自己处理一切运维问题——但这些问题大多是有解的,记下来下次就不会再栽。

这篇博客本身就是从 NAS 上的 Gitea 仓库 commit、push 到远程服务器部署的。工具链跑顺之后,有一种踏实感。

← 返回文章列表