☰
一键部署脚本:让旧电脑变身NAS家庭服务器
2026/10/5 3:33:44 网站建设 项目流程

先说结论:一台退役的旧电脑,装好系统后跑一段我整理好的一键部署脚本,就能变成全家都能用的NAS家庭服务器。这篇文章要聊的就是这套脚本合集里每一段脚本解决什么问题、怎么改参数、会踩哪些坑,以及我拿J4105、3865U这些老平台反复折腾后留下的心得。

我自己从前也是“谈NAS就头大”的那类人,尤其是不想花钱买成品NAS,又舍不得扔了吃灰的老笔记本,结果装系统容易,配Samba、配下载工具、配权限、做开机挂载这些步骤全摊开之后,一个周末就没了。后来我把所有重复配置拆成脚本,才发现家庭服务器的门槛大部分来自重复劳动,而不是技术本身有多高。如果你也有一台旧电脑,想搭共享存储、跑下载工具、备份手机相册,又不想在系统配置里反复摔跟头,这套方式能帮你节约大量时间。

这篇文章不会教你买最贵的设备,也不会让你背一肚子参数。我会先讲清楚为什么要用脚本搭NAS,再把脚本里每个模块的作用和关键参数写明白,最后附上可照抄的部署流程和一份实用排查清单。零基础可以直接上手,有基础的也能拿去改成自己的版本。

1. 我为什么把全家存储押注在“一键部署脚本”上

1.1 家庭服务器的需求其实很少

普通家庭里,NAS真正被高频使用的功能掰着手指头数得过来:手机照片自动备份、电脑和电视能直接播放下载好的影片、家人之间互传大文件、夜里挂个下载任务,再往深一点是监控摄像头录像、智能家居联动这类加分项。需求简单,但DIY的步骤并不简单。

给旧电脑搭NAS,你至少要做这些事:装一个Linux系统,选择文件系统,划分目录,安装Samba,配置用户权限,处理防火墙端口,设置开机自动挂载硬盘,再想方设法让Docker容器里的服务能稳定跑起来。每一项单独看都不复杂,连起来却能吃掉一整个周末,而且换一台机器、换一块硬盘,这些坑大概率要重新走一遍。脚本化的核心价值就是把这些“我知道怎么配”的步骤,变成“机器自己配”。

1.2 脚本设计的三个原则

我这套脚本从第一版到现在,反复改过好几轮,最终只保留了三个原则。

第一个原则是幂等性。脚本可以重复执行,不会因为跑了两遍就产生重复文件或冲突配置。这一点在调试时特别重要,你改完参数后可以放心重跑,不用提心吊胆怕把系统搞乱。

第二个原则是分阶段。整个部署过程被拆成系统初始化、Docker安装、数据目录规划、容器栈部署四个相互独立的阶段。每个阶段单独执行、单独出日志,哪一步出问题,直接看对应阶段的日志就能定位。

第三个原则是参数外部化。所有IP地址、用户名、密码、目录路径、端口号都集中放在一个config.env文件里,脚本本身不硬编码任何和我家庭环境有关的信息。这样你拿到脚本后,只需改这一个文件,不用翻遍几十个配置文件去替换IP和密码。

1.3 为什么不用成品NAS系统,偏要自己写脚本

群晖、绿联这类成品NAS系统真的很方便,手机App和桌面客户端都给你做好了,拿回来插上硬盘就能用。飞牛NAS这类国产系统近两年讨论度也很高,安装教程铺天盖地。那为什么还要自己用脚本搭?

最直接的原因是硬件自由度。成品系统对自家硬件适配最好,装到老电脑上偶尔会出现网卡认不出、休眠唤醒异常、App远程访问受限等奇怪问题。自己装Debian再跑脚本,底层系统换成了通用Linux发行版,硬件兼容面一下扩大很多。另一个原因是透明可控。脚本每一行都摆在那里,出了问题能直接定位,不用在一个封装好的黑盒里猜来猜去。对普通用户来说成品系统没问题,但如果你手头正好有旧电脑,又想真正了解NAS背后发生了什么,脚本方案会是更合适的起点。

2. 脚本合集全拆解:每个模块到底帮你省掉什么

2.1 系统初始化:先把地基打稳

第一阶段脚本做的事是系统初始化。包括更新软件包索引、升级系统、设置时区、开启SSH、安装后续会用到的常用工具,比如curl、wget、nano、vim、rsync、unzip这些。很多人会觉得这一步没必要,其实它是后面所有操作的基础。

新装的Debian系统默认源在国外,在国内下载速度往往很慢。脚本会把软件源自动切换成你所在区域更常用的镜像源,然后才执行apt upgrade。更新和升级要分开跑,避免升级过程中断网导致软件源状态异常。时区默认设为Asia/Shanghai,这样日志时间和你的生活习惯一致,排查问题的时候不用做时区换算。

另外我建议在这步顺手做两件安全相关的事:修改SSH默认端口,并禁止root账号密码登录。NAS长期挂在家庭网络中,如果把默认端口暴露到公网,被扫描爆破只是时间问题。脚本只做基础加固,更复杂的安全策略可以以后再补。

2.2 存储挂载与目录规划:给数据找一个固定座位

第二阶段是存储挂载和目录规划,这是整套脚本里最不能被跳过的一步。硬盘挂载如果做得随意,后面所有应用都可能出奇奇怪怪的权限问题。

脚本会读取config.env里的磁盘信息,把数据盘格式化或直接挂载到 /data 目录,然后生成一套固定的目录结构。我的习惯是分得细一点:

/data ├── downloads # 临时下载目录 ├── media # 电影、剧集、音乐 ├── photos # 手机相册备份 ├── backup # 各类备份产物 └── appdata # Docker容器配置和数据库

目录规划好以后,脚本会生成fstab条目,实现开机自动挂载。这里有个关键细节:fstab里必须写UUID,不能写 /dev/sda 这种设备名。因为Linux在开机时检测硬盘的顺序不一定固定,多块硬盘的情况下设备名可能互换,出现过一次开机后挂载错盘的情况,数据没坏也被吓得不轻。

文件系统方面,普通家用我建议直接ext4,综合稳定性和恢复工具成熟度都是首选。如果你愿意折腾新特性,Btrfs也可以,支持CoW和快照,但快照功能对新手来说容易把空间越吃越大,我默认脚本走ext4,想换Btrfs可以在变量文件里改。

2.3 Docker安装与镜像源自动切换

Docker是现代NAS生态的事实标准,几乎所有开源家庭服务都提供Docker镜像,容器隔离让服务之间互不干扰,升级或卸载也干净。脚本第二件事就是安装Docker。

系统是纯净Debian时,安装Docker继续用官方脚本并不总是一帆风顺,因为有些依赖源响应很慢。我的脚本会先换源,再安装 docker-ce、docker compose插件,同时顺手把当前用户加入docker用户组,省去每次敲sudo的麻烦。

然后是一个经常困扰群晖和自建NAS用户的环节:容器镜像拉不下来。群晖的Container Manager有时在镜像下载阶段卡住,自建Docker也有同样问题。这不是Docker本身坏了,而是公共镜像仓库在特定网络环境下访问不稳定。脚本的做法是把Docker的registry mirror写入 /etc/docker/daemon.json,并配置多个国内可达的公共镜像源。脚本在拉取镜像失败时还会自动重试并切换到下一个可用源。建议不要把镜像源写死到一个,公共镜像源偶尔会调整,多备几个能明显减少“明明照着教程做的,镜像却拉不下来”的情况。

daemon.json大致长这样:

{ "registry-mirrors": [ "https://mirror.example1.com", "https://mirror.example2.com", "https://mirror.example3.com" ] }

改完配置记得重启Docker服务才能生效,脚本里已经做了这一步。

2.4 用户权限与PUID/PGID:容器不听话的根源

权限问题大概是NAS自建过程中最容易让人抓狂的。Docker容器默认可以用root运行,但如果所有容器都以root写文件,宿主机的数据目录就会变成一堆root用户拥有却无法用普通账号管理的文件。

脚本会创建名为nas的普通用户,UID和GID默认为1000,并把 /data 目录交由这个用户管理。然后每个容器模板里都设置了PUID和PGID这两个环境变量,让容器内的进程以宿主机的nas用户身份运行。

PUID=1000 PGID=1000

原理其实不难理解:容器里的进程虽然有独立的文件系统视角,但写入宿主机目录时仍以内核看到的UID/GID为准。只要容器内的UID和宿主机上的UID一致,两边就能认作同一个用户,文件权限自然就理顺了。这个参数是几乎所有容器部署的通用约定,哪怕你以后不用我的脚本,自己写docker-compose时也建议遵守。

2.5 容器模板:用Compose统一管理服务

第四阶段是容器栈部署,脚本不直接docker run,而是统一使用docker compose管理。每个服务单独一个yaml文件,但最终都在同一个项目目录下,方便整体启停和查看日志。

典型的服务组成如下:

services: qbittorrent: image: lscr.io/linuxserver/qbittorrent:latest container_name: qbittorrent environment: - PUID=1000 - PGID=1000 - TZ=Asia/Shanghai volumes: - /data/appdata/qbittorrent:/config - /data/downloads:/downloads ports: - 8080:8080 - 6881:6881 - 6881:6881/udp restart: unless-stopped jellyfin: image: lscr.io/linuxserver/jellyfin:latest container_name: jellyfin environment: - PUID=1000 - PGID=1000 volumes: - /data/appdata/jellyfin:/config - /data/media:/media ports: - 8096:8096 restart: unless-stopped

这里有两个容易忽略的设计:所有容器都放了PUID/PGID,所有持久化数据都放在 /data/appdata 下的独立子目录,并且容器都设置了 restart: unless-stopped。意味着只要服务没被手动停止,开机后就会自动拉起,故障重启也不会让服务长期离线。后面加新服务时,照着这个模板复制一份再改端口和卷即可。

3. 手把手实操:从小白到跑起家庭服务器的完整流程

3.1 硬件准备与老平台选型

一台旧电脑、一块硬盘、一个普通路由器,差不多就是最低配置。实际部署中我更推荐用迷你主机或淘汰的笔记本,因为相比老式ATX机箱,这两类设备功耗更低、噪音更小,放在客厅或弱电箱里不占地方。

CPU方面,很多人在J4105和3865U之间纠结。J4105是四核四线程,TDP 10W,支持4K硬解;3865U是双核四线程,TDP 6W,省电但核显解码能力弱。如果你打算用Jellyfin做视频转码,J4105明显更合适;如果只是纯存储加下载工具,3865U足够,而且更安静。下面是实际使用中的对比:

对比项J41053865U
核心线程4核4线程2核4线程
默认TDP10W6W
4K硬解支持基本不指望
Jellyfin软转码可应付1080P吃力
适合场景影音+存储+轻服务纯存储+下载

内存建议至少8GB,Docker多开服务后4GB会经常看到内存告警。硬盘可以用机械盘,如果预算允许加一块固态做系统盘,Docker镜像和容器配置放在SSD上,机械盘专门装数据,性能感受会好很多。

3.2 安装Debian后下载脚本

系统建议装Debian 12的minimal版。安装过程中不需要选任何额外的桌面环境和软件包,越纯净越好,因为所有东西都由脚本接管。

系统装好后,用SSH登录,把脚本合集拉到机器上。国内网络访问GitHub不稳定的话,我一般都同步在Gitee,代码仓库里有两个分支,实际使用直接用Gitee地址就行。

git clone https://gitee.com/example/nas-deploy-scripts.git cd nas-deploy-scripts cp config.env.example config.env

打开config.env后,你会看到这样一个结构:

# 基础设置 NAS_USER=nas NAS_UID=1000 NAS_GID=1000 TIMEZONE=Asia/Shanghai # 数据目录 DATA_DIR=/data # 需要挂载的存储设备UUID,多个用空格隔开 DISK_UUIDS="" # 各服务端口 QBITTORRENT_PORT=8080 JELLYFIN_PORT=8096 SAMBA_SHARE=/data/media

密码等敏感信息只写在这个文件里,脚本会在本地引用,不会打印到日志,更不要把这个文件传到公开仓库。这一步值得多花五分钟逐项确认,尤其磁盘UUID,用blkid命令查好再填,不要填错。

3.3 核心脚本逐行解析

以第二阶段脚本为例,它其实就是一个严格按照顺序执行的bash脚本。关键部分类似这样:

#!/usr/bin/env bash set -euo pipefail # 加载变量 if [ -f config.env ]; then set -a source config.env set +a fi # 创建数据目录 sudo mkdir -p ${DATA_DIR}/{downloads,media,photos,backup,appdata} # 将硬盘写入fstab for uuid in ${DISK_UUIDS}; do echo "UUID=${uuid} ${DATA_DIR} ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab done # 挂载全部 sudo mount -a # 修正权限 sudo chown -R ${NAS_USER}:${NAS_USER} ${DATA_DIR} sudo chmod 0755 ${DATA_DIR}

set -euo pipefail 的作用是:脚本任何一行出错就立刻停止,变量没有定义就报错,管道命令只要有一个环节失败整体算失败。这样不会出现脚本跑了半天、最后发现前面早已出错的情况。nofail选项很关键,开机时即使某块硬盘没接上,系统也不会卡在挂载步骤进不了系统。

每执行完一个阶段脚本,可以看一下输出的日志,确认没有红色报错再进入下一阶段。第一次跑的时候建议用普通用户执行,需要sudo的地方脚本会提示输入密码,不要干脆用root跑完所有流程,后面权限容易混乱。

3.4 启动容器与首次访问

容器部署脚本执行完后会自动运行docker compose up -d,把模板里定义的所有服务拉起来。首次启动会拉取镜像,时间取决于网络和机器性能,耐心等就好。配置了镜像源的情况下,大部分镜像几分钟内都能拉完。

启动完成后,你会得到一堆访问入口:

qBittorrent 管理界面: http://NAS_IP:8080 Jellyfin 媒体服务: http://NAS_IP:8096 Samba 网络共享: \\NAS_IP\media Immich 相册备份: http://NAS_IP:2283

默认账号和初始化密码都写在config.env里,首次登录时按容器提示修改即可。如果看到服务没有起来,可以先执行docker compose logs查看容器日志,这个命令比到处翻系统日志直观得多。

4. 常见问题与排查技巧实录

4.1 镜像拉不下来或超时

这是自建NAS遇到频率最高的问题。表现是docker compose up时卡在Pulling,或者在群晖Container Manager里镜像一直转圈。除了网络因素,镜像源不稳定也是常见原因。

我的排查顺序是:先手动执行 docker pull 其中一个镜像看报错内容;再确认daemon.json里的registry-mirrors是否生效;最后重启Docker服务,不要只重试不重启。脚本里已经内置了镜像源切换机制,但还是建议你在部署方案里把常用镜像尽量用国内可达的源。另外,有些老教程会让你写单个源,遇到它失效整个环境就瘫痪了,多源配置能明显降低这种风险。

4.2 磁盘空间明明很大,却提示写入失败

新装系统有时会出现根分区只有几十GB,数据盘却有好几TB的情况。Docker默认把镜像和容器数据放在 /var/lib/docker,如果这个目录在根分区里,下载几个镜像后根分区就满了,而你的大硬盘还空着。

遇到这个情况,要么把Docker数据目录迁移到数据盘,要么在挂载时直接把 /var/lib/docker 作为一个独立数据盘挂载点。脚本里我默认把 /data/appdata 和Docker数据目录都放在数据盘上,避免系统盘被塞满。排查空间时用 df -h 一条命令,先看哪个分区逼近100%,再顺着目录用 du -sh * 找大文件。

4.3 Windows网络共享连不上或拷贝文件掉速

Samba配置看起来简单,实际表现却经常让人意外。最常见的包括:从Windows资源管理器输入 \IP 后提示无法访问、能看到共享文件夹但拷贝大文件速度只有几MB/s、过一会儿连接就断开。

优先检查SMB协议版本。老的SMB1协议在默认配置里早就被禁了,而网上的老教程还在让你改注册表开启SMB1,完全不建议。Linuxserver的Samba镜像默认支持SMB2/3,够用。其次是防火墙,Debian自带的ufw或者路由器的防火墙如果拦了445端口,Windows会提示很模糊的“无法访问”错误。速度慢时先确认是否连了WiFi,2.4GHz频段跑满可能也就50Mbps,换网线或5GHz频段会立即改善。再就是看机械盘是不是在同时做其他读写,这不是Samba的问题,而是硬盘性能到达瓶颈。

4.4 容器内文件权限变成nobody或者无法删除

这是新手最容易踩的坑。比如容器创建后,外面看媒体文件的所有者变成了nobody,或者想通过宿主机删除一个文件却提示没有权限。根本原因就是容器的UID和宿主机用户UID不一致。

解决方案也很直接:确定你希望哪个系统用户拥有数据,就把所有相关容器的PUID和PGID设成这个用户的UID/GID。已经写坏权限的目录,先在宿主机执行chown,再重新创建容器。我不建议为了省事直接 chmod -R 777,那会让所有服务都能读写你的数据,一旦有一个容器被渗透或误操作,整个资料库都暴露风险。正确做法是用chown把属主锁定到NAS账户,然后给其他用户只读或不可访问权限。

4.5 老电脑CPU占用高,风扇半夜呼呼响

旧处理器性能有限,开了一堆容器后CPU长期50%以上很常见。但风扇吵不一定真是负载问题,也可能是系统默认策略让风扇在高转速下不下来,或者某个容器在后台做周期性扫描。

先通过 docker stats 看每个容器的CPU和内存占用,找到吃资源最狠的那一个。qBittorrent做种功能如果在跑大量任务,CPU占用会直线上升;Jellyfin如果没有硬解,播放4K视频时会用CPU软解,占用率瞬间飙满。脚本模板里会为每个容器设置内存限制,例如:

deploy: resources: limits: memory: 1G

这样单个容器最多占用1GB内存,不会把整个NAS拖垮。如果你用的是3865U这类弱U,还需要降低预期,不要在同一台机器上同时跑转码、虚拟机和高负载下载。

4.6 备份与还原容易踩的坑

我在这上面吃过亏。最开始写的备份脚本只打包了容器配置目录,结果系统需要重装时,发现自己忘备份fstab和网络配置,整个恢复流程变成了手工重配大战。

正确的备份应该包含几部分:数据目录、容器配置目录、数据库备份、系统关键配置文件。我的backup脚本会把 /etc/fstab、/etc/docker/daemon.json、config.env 一起打包,再加一份容器列表清单。还原时先恢复系统配置文件,再按脚本重新安装Docker,最后拉取容器配置,整体流程十五分钟就能完成。

真正让我安心的是在备份后做恢复演练。备份文件能正常生成不代表能成功还原,至少测试一次restore脚本,把备份内容恢复到另一台机器或另一块硬盘上。这里面的常见错误是备份时没有排除缓存和日志文件,tar包越来越大,还原后Docker容器启动失败。备份脚本里我把每个容器的临时目录、cache、log都做了exclude,具体排除规则可以参考tar的--exclude参数。

5. 把脚本往外再延伸:更聪明的家庭服务器

5.1 成品NAS系统和脚本方案怎么选

很多人在一开始都会纠结,到底买群晖/绿联,还是自己搭。这里我给一个不含偏见的对比:

对比项成品NAS系统脚本自建NAS
上手难度低,开箱即用中,需要一次部署
硬件兼容限定自家设备几乎兼容所有x86主机
应用生态应用中心,数量一般Docker生态,丰富很多
App体验官方App成熟依赖容器自带WebUI
硬件成本较高旧电脑零成本可复用
可定制性偏低完全透明

飞牛NAS这类国产系统也很适合大众用户,安装教程很详尽,用起来比自建简单不少。但脚本方案最大的吸引力在于透明和复用:配置好了就是这么一套流程,以后换机器跑一遍脚本就能迁过去。两者没有高下,只看你的目标是什么。如果希望全家人都能轻松用App操作,成品系统更省心;如果为了把旧物利用起来并完全掌控自己的数据,脚本方案会越用越顺手。

5.2 J4105 和 3865U 到底怎么选

补充一点实操中的感受。J4105虽然TDP比3865U高4W,但实际满载和待机功耗差距并没有参数上那么大,多出来的性能换来的是Jellyfin硬解、家人在线看片、偶尔跑点同步任务的时候不会卡。3865U优势在绝对安静和低功耗,适合长期只挂一块硬盘、跑Samba和下载工具的老旧设备。

如果这块NAS还要做照片AI识别、视频转码这类重活,3865U会明显力不从心。反过来,如果只是做个“网络硬盘”,连相册识别都不打算用,3865U完全够。预算允许的话,我更推荐关注J4125或N100这类更新平台,它们功耗和性能更均衡,但本文原则是不增加额外开销,所以旧设备有什么就用什么。

5.3 家庭NAS上值得跑的Docker应用清单

分享一份我实际在用的应用清单,这些都是社区活跃度很高、维护稳定的项目:

  • Jellyfin / Emby:家庭影院中心,统一刮削封面,支持多端播放。
  • qBittorrent / aria2:下载工具,网页管理,挂到 /downloads 目录。
  • Immich / PhotoPrism:手机相册自动备份,带人脸识别和相册分类。
  • Home Assistant:智能家居中枢,把所有智能设备统一接入。
  • Netdata / Zabbix Agent:NAS运行状态监控,能看CPU、内存、磁盘、网络。
  • rclone:定时同步到对象存储或远端目录,做异地备份。
  • Calibre-Web / Komga:电子书和漫画管理,家庭阅读库。

这里有一个经验:不要把一堆服务全塞在一个NAS上,尤其老电脑性能有限。先跑存储、下载、媒体三个核心服务,稳定运行一个月后再加Home Assistant或监控。每加一个新容器,都要确认它不会和已有服务抢占端口,不会因为共享同一个目录造成权限冲突。compose模板里端口冲突会直接报错,看到Address already in use时,在config.env里把端口换掉重跑即可。

5.4 NAS下的IPTV设置与智能音箱联动

最后聊两个有意思的扩展。

一个是NAS下IPTV设置。运营商的IPTV信号在家庭内网中通常以组播方式传输,普通WiFi设备直接播放组播流往往卡顿或无法播放。常见做法是在NAS上跑一个udpxy容器,把组播流转换成HTTP单播流。比如IPTV源地址是 udp://239.x.x.x:5140,udpxy会把它转成 http://NAS_IP:4022/udp/239.x.x.x:5140 这样的链接,手机播放器、电视和电脑都能直接播放,家里所有设备看直播就都顺了。脚本里可以单独加一个udpxy容器,端口按需设置。

另一个是飞牛NAS或自建NAS与小爱音箱、豆包的集成。实现路径一般是通过Home Assistant,把NAS的磁盘状态、下载完成通知、备份结果通过小爱音箱播报;或者通过豆包这类大模型接口,让语音助手能回答家庭数据相关的简单问题。核心逻辑是让NAS在本地作为家庭自动化中枢,通过API把消息推给音箱,再通过云端的意图识别返回结果。API Key要保存在本地配置文件里,不要进入git仓库或公开博客。这个玩法对NAS性能要求不高,3865U也能带得动,适合作为搭好NAS之后的进阶项目。


这套脚本我前后迭代了很长时间,刚开始也踩过不少坑:第一次重装系统前没备份fstab,结果所有容器配置全部清零,一夜回到解放前。后来学乖了,备份脚本里连系统关键配置一起打包,之后再也没有慌过。如果你第一次搭NAS,我的建议很朴素:先跑通存储和共享,稳定后再慢慢加应用。脚本能帮你省掉重复配置的时间,但真正值得花心思的永远是数据目录怎么规划、备份怎么做,那才是家庭服务器能不能长久用下去的关键。

最后分享一个经常被忽略的小技巧:每次执行脚本前,把当前系统里的服务状态和磁盘分区信息导一份留存。以后排查“上次明明是好的”这种问题时,至少有一份对照依据。希望这份记录能让你少走几段弯路,也欢迎你把自己的经验沉淀到社区的讨论帖里,让更多后来者少栽跟头。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询