1. 为什么我劝你先想清楚“最简”到底简在哪
很多人一听到“NAS搭建网盘+博客”,脑子里立刻浮现出一堆教程:Docker、Nginx、SSL证书、反向代理、数据库、对象存储……光是名词就劝退一大半。我当初也是这么被吓住的,直到自己真正动手跑了一遍才发现,所谓“最简方案”的核心不是功能最少,而是决策路径最短——你不需要在几十个方案里反复横跳,只需要选一条被验证过、依赖最少、出问题最容易定位的路线。
先明确这套方案能做什么:在一台家用NAS上,同时跑起一个私有网盘(用来存照片、文档、备份手机相册)和一个个人博客(用来写长文、记录折腾过程、对外分享)。两者共享同一台设备的存储和网络,互不干扰。适合谁?适合手里已经有一台NAS(或者准备入手入门级型号)、懂一点基础操作但不想折腾复杂架构的人。如果你连SSH都没用过,也没关系,我会把每一步的意图讲清楚,你照着做就行。
这里有个关键判断:网盘和博客虽然都是“对外提供服务”,但它们对稳定性和资源占用的要求完全不同。网盘是高频读写、大文件传输、需要权限控制;博客是低频写入、小文件读取、对公网访问更敏感。把这两个需求拆开看,你才能理解为什么后面的部署方案要那样设计,而不是随便找个“一键脚本”糊上去。
我见过太多人一上来就追求“全功能”:要支持在线编辑、要支持多用户协作、要支持自动备份到异地。结果配置了三天,最后连外网访问都没打通,热情直接耗尽。所以这篇内容的核心思路是:先用最小可行方案跑通闭环,再按需叠加功能。下面我会从硬件选型、系统准备、网盘部署、博客部署、外网访问、日常维护六个层面,把每一步的“为什么”和“怎么做”都摊开讲。
2. 硬件与系统底子:别让设备成为瓶颈
2.1 NAS选型:x86还是ARM,这是个问题
如果你还没买设备,这一步值得花十分钟想清楚。市面上入门NAS主要分两类:ARM架构(多为品牌成品,如某晖、某空间)和x86架构(多为自组或中端成品)。ARM的优势是功耗低、噪音小、价格便宜,缺点是Docker生态兼容性差,很多镜像跑不起来。x86的优势是性能强、兼容性好,缺点是功耗和价格都上去了。
我的建议很直接:如果你确定只跑网盘和博客这两个服务,ARM完全够用。这两个服务对CPU的占用极低,网盘主要吃硬盘IO和网络带宽,博客主要吃内存(数据库查询)。一颗四核ARM处理器加2GB内存,跑起来毫无压力。但如果你后续想加媒体服务器、虚拟机、或者需要转码,那就直接上x86,别犹豫。
这里有个容易被忽略的点:内存比CPU更重要。网盘服务在传输大文件时会占用较多内存做缓存,博客的数据库也需要常驻内存。2GB是底线,4GB会舒服很多。如果你用的是成品NAS,买之前一定确认内存是否可扩展,板载不可扩展的型号后期会很被动。
2.2 存储规划:系统盘和数据盘必须分开
这是血泪教训。很多人图省事,把系统、网盘数据、博客数据全塞在一块硬盘上。结果某天系统崩了要重装,数据全在同一个盘里,格式化也不是、不格式化也不是。正确的做法是:系统装在一块小容量SSD上,数据放在单独的数据盘上。
具体操作上,如果你用的是成品NAS,通常有专门的系统分区,你只需要把数据盘挂载到指定目录即可。如果是自组NAS,建议用一块128GB以上的SSD做系统盘,一块或多块大容量机械硬盘做数据盘。数据盘的文件系统选择上,ext4是最稳妥的选择,兼容性好、恢复工具多;如果你需要快照功能,可以考虑btrfs,但要注意它的稳定性在部分场景下不如ext4。
挂载点的规划也要提前想好。我习惯把数据盘挂载到/mnt/data,然后在下面建两个目录:/mnt/data/cloud给网盘用,/mnt/data/blog给博客用。这样做的好处是,后面无论怎么折腾服务,数据始终在固定位置,迁移和备份都很清晰。
2.3 系统选择:轻量优先,别给自己找麻烦
NAS操作系统选择很多,成品NAS自带系统就不说了,自组的话常见的有某晖引导、某牛、某U等。对于“最简方案”这个目标,我推荐直接用轻量级Linux发行版,比如Debian或者Ubuntu Server。原因很简单:Docker支持完善、社区资料多、出问题容易搜到答案。
不推荐用桌面版系统,因为图形界面会占用额外资源,而且很多桌面环境自带的网络管理组件会和Docker的网络配置冲突。我试过在桌面版上跑Docker,结果容器网络死活不通,排查了半天才发现是NetworkManager在捣乱。Server版没这个问题,干净利落。
安装系统时有一个关键设置:开启SSH服务。后面所有操作都通过SSH完成,比在NAS本机上接键盘显示器方便得多。如果你不熟悉命令行,也不用怕,我会把每条命令的作用都解释清楚,你复制粘贴就行。
3. 网盘部署:用Docker跑起你的私有云
3.1 为什么选这个网盘方案
私有网盘方案很多,有老牌的、有新秀的、有主打同步的、有主打分享的。对于“最简”这个目标,我选择的是某款基于Web的轻量级网盘系统(具体名称不点名,避免广告嫌疑,你搜“轻量私有网盘 Docker”就能找到)。它的特点是:单容器部署、自带Web界面、支持多用户、支持文件分享链接、支持手机App。
为什么不选功能更强大的方案?因为功能越强,依赖越多,出问题的概率越大。我试过某款功能非常全的网盘系统,结果它依赖数据库、缓存、消息队列三个额外容器,光是调通它们之间的网络就花了一晚上。而轻量级方案一个容器搞定,数据直接存在文件系统里,备份就是复制文件夹,简单到极致。
3.2 Docker环境准备:三行命令的事
如果你用的是Debian或Ubuntu Server,安装Docker只需要三条命令。先更新包索引:
sudo apt update && sudo apt upgrade -y然后安装Docker的官方脚本:
curl -fsSL https://get.docker.com | sudo sh最后把当前用户加入Docker组,这样后面不用每次都加sudo:
sudo usermod -aG docker $USER执行完最后一条命令后,你需要退出SSH重新登录,用户组变更才会生效。这个细节很多人会忽略,然后发现docker ps报权限错误,以为是安装出了问题。
验证安装是否成功:
docker run hello-world如果看到“Hello from Docker!”的输出,说明环境没问题。
3.3 网盘容器部署:参数逐个拆解
部署命令看起来很长,但每个参数都有明确意图。我先把完整命令列出来,然后逐条解释:
docker run -d \ --name cloud \ --restart unless-stopped \ -p 8080:80 \ -v /mnt/data/cloud:/var/www/html/data \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Asia/Shanghai \ lightweight-cloud-image--name cloud是给容器起个名字,方便后续管理。--restart unless-stopped是关键,它保证NAS重启后容器自动启动,不需要你手动去拉起来。-p 8080:80把容器的80端口映射到NAS的8080端口,这样你访问http://NAS的IP:8080就能打开网盘界面。
-v /mnt/data/cloud:/var/www/html/data是数据卷映射,冒号左边是NAS上的真实路径,右边是容器内的路径。所有上传的文件都会存在/mnt/data/cloud下面,你随时可以在文件管理器里看到它们。PUID和PGID设置容器内运行用户的ID,必须和NAS上你的用户ID一致,否则会出现文件权限问题。用id命令可以查看当前用户的UID和GID。
TZ=Asia/Shanghai设置时区,不设置的话容器内时间是UTC,日志时间会对不上。
注意:如果你NAS的8080端口已经被占用,把左边的数字改成其他端口即可,比如
-p 8081:80。右边容器内的80端口不要改。
3.4 初始化与权限踩坑实录
容器启动后,用浏览器打开http://NAS的IP:8080,应该能看到网盘的初始化界面。第一次访问会让你创建管理员账号,设置好用户名和密码。
但这里有个坑我踩过:创建完账号后,上传文件提示“权限不足”。原因是容器内的用户虽然设置了PUID和PGID,但/mnt/data/cloud目录的属主可能还是root。解决办法是在NAS上执行:
sudo chown -R 1000:1000 /mnt/data/cloud把目录属主改成你的用户。如果你不确定自己的UID,用id命令看一下,把1000替换成实际值。
另一个常见问题是上传大文件时中断。这通常是PHP的上传限制导致的。你需要进入容器修改PHP配置:
docker exec -it cloud bash然后编辑/etc/php/8.x/apache2/php.ini(具体路径取决于镜像),把upload_max_filesize和post_max_size改大,比如改成2048M。改完重启容器生效。这个操作在容器重建后会丢失,所以更稳妥的做法是在部署时就把配置文件挂载出来,但那是进阶操作,初期可以先手动改。
4. 博客部署:静态还是动态,选错多花三小时
4.1 博客方案的核心取舍
博客系统分两大阵营:静态博客和动态博客。静态博客是本地生成HTML文件,然后通过Web服务器托管,优点是极快、极安全、几乎不占资源;动态博客是每次访问都查询数据库生成页面,优点是后台管理方便、插件丰富。
对于NAS场景,我的建议是:如果你主要目的是记录和分享,选静态博客;如果你需要多人协作、频繁在线编辑,选动态博客。静态博客在NAS上的优势太明显了——不需要数据库容器、不需要PHP容器,一个Nginx容器就能跑,资源占用几乎可以忽略。
我最终选择的是某款基于Go语言的静态博客生成器(搜“Go 静态博客 单文件”能找到),它的特点是:单个二进制文件、无依赖、自带Web管理后台、支持Markdown写作。你可以在NAS上跑一个它的服务端,通过浏览器写文章,它自动生成静态页面。
4.2 静态博客容器部署:比网盘还简单
部署命令如下:
docker run -d \ --name blog \ --restart unless-stopped \ -p 8090:80 \ -v /mnt/data/blog:/data \ -e TZ=Asia/Shanghai \ static-blog-image和网盘部署几乎一样,只是端口换成了8090,数据目录换成了/mnt/data/blog。启动后访问http://NAS的IP:8090,进入博客后台,设置管理员账号。
这里有一个关键配置项:博客的“站点地址”。你需要在后台把站点地址设置成你最终对外访问的域名或IP,否则生成的页面里所有链接都会指向localhost,外网访问时样式和跳转全乱。如果你暂时没有域名,先填http://NAS的IP:8090,后面有了域名再改。
4.3 写第一篇文章:Markdown就够了
静态博客的写作体验取决于生成器。我用的这款支持在线Markdown编辑器,左边写右边预览,写完点发布,它自动生成HTML文件到/mnt/data/blog目录下。你不需要懂HTML,用Markdown语法写就行。
Markdown的基本语法十分钟就能学会:#是标题,**文字**是加粗,-是列表,[链接文字](网址)是超链接。这些足够你写出结构清晰的博客文章。如果你之前没用过Markdown,我建议先在本地用Typora或者VS Code写几篇练手,熟悉了再搬到NAS上。
提示:博客的图片建议存在网盘里,然后在博客中引用网盘的分享链接。这样图片只存一份,网盘和博客都能用,节省空间。
4.4 静态博客的备份逻辑
静态博客的备份极其简单:整个/mnt/data/blog目录复制走就行。里面是Markdown源文件加生成的HTML文件,没有任何数据库依赖。你甚至可以直接用rsync命令定时同步到另一块硬盘:
rsync -av /mnt/data/blog /mnt/backup/blog这条命令把博客目录完整同步到备份盘。网盘的备份同理,把/mnt/data/cloud同步走即可。这就是为什么我一直强调数据目录要独立挂载——备份的时候目标明确,不会漏掉东西。
5. 外网访问:不折腾端口映射的替代思路
5.1 先搞清楚你的网络环境
外网访问是NAS部署中最容易卡住的环节。在动手之前,你需要先确认一件事:你的宽带有没有公网IP。判断方法很简单,登录路由器管理界面,查看WAN口IP地址,然后和百度搜索“IP地址”显示的结果对比。如果两个IP一致,说明你有公网IP;如果不一致,说明你在运营商的大内网里。
有公网IP的话,事情简单很多:在路由器上做端口映射,把NAS的8080和8090端口映射到公网,然后通过http://你的公网IP:端口访问。但这样做有两个问题:一是公网IP可能会变(动态IP),需要配合动态域名解析服务;二是直接暴露HTTP端口不安全,建议配合反向代理和HTTPS。
没有公网IP的话,端口映射这条路就走不通了。替代方案是内网穿透或者异地组网。这两类工具的原理是在你的NAS和外部网络之间建立一条加密隧道,让你在外网也能访问内网服务。具体工具名称我不展开,你搜“内网穿透 NAS”能找到很多选择。选择时注意两点:一是是否支持HTTPS,二是免费版是否有带宽限制。
5.2 反向代理:一个入口管理两个服务
无论你用哪种外网访问方式,我都强烈建议加一层反向代理。反向代理的作用是:你只需要暴露一个端口(比如443),然后根据访问的域名或路径,把请求转发到内网的网盘或博客服务。这样做的好处是:管理方便、可以统一配置HTTPS、隐藏内部端口。
在NAS上跑一个Nginx容器就能实现反向代理。配置文件大概长这样:
server { listen 443 ssl; server_name cloud.yourdomain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://NAS的IP:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } server { listen 443 ssl; server_name blog.yourdomain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://NAS的IP:8090; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }这样配置后,访问https://cloud.yourdomain.com就是网盘,访问https://blog.yourdomain.com就是博客。两个服务共用一个443端口,互不干扰。
5.3 HTTPS证书:别用自签名的
HTTPS证书有三种来源:自签名、免费证书、付费证书。自签名证书浏览器会报安全警告,体验很差,不推荐。免费证书现在很容易获取,某机构提供90天有效期的免费证书,配合自动续期脚本可以一直用。付费证书没必要,个人使用免费证书完全够。
证书的自动续期是个关键点。免费证书90天过期,如果忘了续,网站就打不开了。我用的方案是:在NAS上跑一个证书管理容器,它自动申请证书、自动续期、自动重载Nginx配置。部署一次,后面就不用管了。具体容器名称你搜“HTTPS 证书 自动续期 Docker”能找到。
注意:申请证书需要域名解析到你的公网IP。如果你没有公网IP,证书申请会失败。这种情况下,你可以先用内网穿透工具提供的HTTPS域名,等有了公网IP再自己申请证书。
6. 日常维护:让这套系统稳定跑下去
6.1 更新策略:别追新,要求稳
Docker容器更新很方便,一条命令就能拉取最新镜像。但对于NAS上的生产服务,我建议不要频繁更新。新版本可能引入不兼容的变更,导致服务起不来。我的做法是:每三个月检查一次更新,更新前先备份数据目录,更新后观察一周再决定是否保留。
更新网盘容器的命令:
docker stop cloud docker rm cloud docker pull lightweight-cloud-image # 然后重新执行之前的docker run命令注意docker rm只是删除容器,不会删除数据卷映射的目录,所以数据是安全的。但为了保险,更新前还是手动备份一下/mnt/data/cloud。
6.2 监控:知道服务是不是活着
NAS上的服务跑久了,偶尔会出现容器假死、内存泄漏、磁盘写满等问题。你需要一个简单的监控手段,在出问题时能第一时间知道。最轻量的方案是用Uptime Kuma这类监控工具,它定时访问你的网盘和博客地址,如果返回异常就发通知。
部署Uptime Kuma也是Docker一条命令的事,这里不展开。如果你不想再跑一个容器,也可以用最原始的方法:在NAS上设一个定时任务,每天用curl检查两个服务的HTTP状态码,如果不是200就发邮件提醒。
#!/bin/bash cloud_status=$(curl -o /dev/null -s -w "%{http_code}" http://localhost:8080) blog_status=$(curl -o /dev/null -s -w "%{http_code}" http://localhost:8090) if [ "$cloud_status" != "200" ] || [ "$blog_status" != "200" ]; then echo "服务异常:网盘 $cloud_status,博客 $blog_status" | mail -s "NAS告警" your@email.com fi把这个脚本加到crontab里,每天跑一次。
6.3 磁盘空间:提前设好阈值
网盘服务最怕磁盘写满。磁盘一满,不仅网盘不能上传,博客也可能因为无法写入而报错。我的做法是:在NAS上设一个定时任务,每天检查数据盘的剩余空间,低于10%就发通知。
df -h /mnt/data | awk 'NR==2 {print $5}' | sed 's/%//'这条命令输出数据盘的使用百分比。你可以在脚本里判断,如果大于90就告警。告警方式可以用邮件,也可以用一些通知服务的API。关键是提前知道,而不是等用户反馈“上传不了”才发现。
6.4 我的踩坑清单
最后分享几个我在维护过程中踩过的坑,你大概率也会遇到:
坑一:容器时间不对导致证书续期失败。证书续期对时间敏感,如果容器时区设置错误,续期会报“时间不在有效期内”。解决办法是部署时务必加-e TZ=Asia/Shanghai。
坑二:网盘上传大文件超时。除了前面说的PHP配置,还有一个可能是Nginx的client_max_body_size限制。如果你在网盘前面加了反向代理,需要在Nginx配置里把这个值调大,比如client_max_body_size 2048m;。
坑三:博客图片不显示。静态博客生成器通常会把图片路径写成相对路径,如果你在后台设置的站点地址和实际访问地址不一致,图片就会404。检查后台的“站点地址”设置,确保和浏览器地址栏一致。
坑四:Docker日志占满磁盘。容器运行久了,日志文件会越来越大。可以在Docker的daemon配置里限制日志大小,编辑/etc/docker/daemon.json:
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }然后重启Docker服务。这样每个容器最多保留30MB日志,不会失控。
这套方案我从部署到稳定运行花了大概一个周末,中间踩的坑基本都写在上面了。现在网盘存了全家人的照片和文档,博客也写了十几篇折腾记录,整体运行很稳。如果你照着做遇到问题,大概率是权限或端口冲突,按上面的排查思路走一遍基本能解决。