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 再连一次)。
跑的服务一览
- Docker:一切的基础
- PostgreSQL(端口 5532,避让宿主自带实例)
- Redis(端口 6380,同理避让)
- Gitea:私有 Git 仓库
- Portainer:Docker 可视化管理
- mem0:AI 记忆层服务
踩坑实录
坑一: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:
- PostgreSQL:
5532 - Redis:
6380
这样一眼就能看出是什么服务,也不会跟任何默认端口撞车。
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 镜像经常会失败或极慢。两个办法:
- 配置 Docker 代理:在
/etc/docker/daemon.json里加镜像加速地址(阿里云、DaoCloud 等都有免费加速服务) - 本地拉取再传:在 Mac 上
docker pull+docker save导出 tar,SFTP 传到 NAS,再docker load
方法二虽然土但百分百可靠,适合部署 ARM 架构专用镜像时使用。
写在最后
NAS 自托管的乐趣在于:你拥有对数据的完全控制。Gitea 里存的是你自己的代码,PostgreSQL 里跑的是你自己的数据库,没有哪天服务商会突然关停。代价是你得自己处理一切运维问题——但这些问题大多是有解的,记下来下次就不会再栽。
这篇博客本身就是从 NAS 上的 Gitea 仓库 commit、push 到远程服务器部署的。工具链跑顺之后,有一种踏实感。
← 返回文章列表