从 1 TB 的 Fedora NAS 到 Hexo + Butterfly 个人博客
一块 1 TB 的硬盘装好 Fedora 后,我在终端里看了一眼,准备用来存文件的目录居然只有 15 G。这台机器原本只要满足三个需求:Windows 能存取文件,我能远程管理,一个人用起来省心。把这 15 G 弄明白之后,我又给它加了一项工作。现在你读到的这篇文章,就是它从家里发出来的。
把 Fedora Server 做成自己的 NAS 安装盘
我从 Fedora Server 45 的 x86_64 DVD 镜像出发,把一次次手动配置的部分放进了定制 ISO。安装盘多了一个启动项 Install Personal NAS (Fedora 45)。里面的 Kickstart 负责安装所需软件、放好 Samba 配置,并带上首次使用的 nas-setup 脚本。硬盘选哪块、分区怎么用、管理员账号叫什么,仍在安装界面里决定。
拆开这张盘,能看到 nas.ks(安装指令)、nas/payload.tar(自用配置和脚本),以及随盘带的离线 RPM。安装时会校验内置文件和软件包签名。这样,重装后拿到的是同一套共享和管理工具,而账号与家庭网段可以在每台机器上单独设置。
做好的文件是 Fedora-NAS-45-x86_64.iso,旁边有一份 .sha256 校验文件。在 Windows 上,可以用下面这条 PowerShell 命令计算镜像的 SHA-256,和校验文件对照,再用 Fedora Media Writer 的“自定义镜像”写 U 盘。
1 | Get-FileHash .\Fedora-NAS-45-x86_64.iso -Algorithm SHA256 |
这台机器的 NVMe 上已经有 NTFS 分区,安装时保留了它们。后面建 NAS 数据卷,用的是 Fedora 卷组里的空闲空间。这个区别很要紧:磁盘列表里能看见一块 1 TB 的盘,不等于整盘都可以格式化。
1 TB 的盘,为什么共享目录只看见 15 G?
第一次检查时,我用了三条命令。它们分别回答“这个目录实际落在哪个文件系统”“卷组还有多少空间”和“空间已经分给了哪些逻辑卷”。
1 | df -hT /srv/nas/data |
当时 df 显示的是挂在 / 上的根卷,总共 15 G。vgs 却显示卷组约 794.53 GiB,其中约 779.53 GiB 还没分配。原因一下就清楚了:/srv/nas/data 当时只是根卷上的一个目录。即使 Windows 能往这个目录写,文件也只会把系统盘填满。
处理时,我从卷组的空闲空间划出逻辑卷 nasdata,在新卷上建立 XFS,把它挂到 /srv/nas,再在挂载后的卷上准备 data 目录。已经存过文件的机器要先备份或迁移旧目录里的文件;新卷一挂上去,原目录的内容会被遮住。
1 | findmnt --mountpoint /srv/nas |
这次 findmnt 显示 nasdata、xfs 和 /srv/nas,df 显示总量 671 G、当时可用 658 G。这才是 Windows 共享真正能用的空间。要让挂载在重启后恢复,可以在 Cockpit 的存储页为这个卷设置固定挂载点,或按文件系统 UUID 写入 /etc/fstab。重启后再跑上面两条命令,就知道共享目录是否仍在数据卷上。
在 Windows 里打开 Data
在 Fedora 上用安装时创建的普通管理员登录,运行这张定制镜像自带的首次配置命令。
1 | sudo nas-setup |
Fedora login to use for the Data share [root]: 这句曾把我问住。这里要填的是刚创建的普通 Fedora 用户名。即使括号里写着 root,也要手动输入自己的账号。接着选家庭局域网的网卡,设置独立的 SMB 密码。脚本配置 Data 共享,给 /srv/nas/data 加上 SELinux 的 samba_share_t 标签,并启动 Samba、SSH 和 Cockpit。
下面用 192.168.1.50 和 nasuser 举例。实际连接时,换成 nas-setup 输出的局域网地址和自己的用户名。
| 我想做的事 | 从 Windows 打开 | 使用的凭据 |
|---|---|---|
| 存取文件 | 资源管理器地址栏输入 \\192.168.1.50\Data |
nasuser 和 SMB 共享密码 |
| 网页管理 | 浏览器打开 https://192.168.1.50:9090 |
Fedora 用户名和系统密码 |
| 远程终端 | PowerShell 执行 ssh [email protected] |
Fedora 的 SSH 登录凭据 |
第一次点共享时,Windows 只弹出一句“无法访问”,没有足够信息判定原因。再碰到这个提示,我会先在 PowerShell 运行 Test-NetConnection 192.168.1.50 -Port 445。如果 TcpTestSucceeded 是 False,先查地址、网络和服务;如果是 True,再查共享名、共享密码和 Windows 保存的旧凭据。这样可以把“连不到机器”和“登录被拒绝”分开。
后来从迅雷云盘往 NAS 拷文件,资源管理器先显示 41.6 MB/s,一度又跳到 251 MB/s。单条千兆链路的理论上限只有 125 MB/s,还没扣协议开销。云盘、缓存和资源管理器的瞬时读数混在一起,那两张图无法测出交换机的实际吞吐量。要测局域网,我会改用 Windows 本地 SSD 上的一个大文件,复制到共享目录,按文件大小和完整用时算平均速度。
给博客单独留一个公网入口
NAS 配好后,我想用同一台机器写个人博客。最初的 NAS 配置里,我试过 Tailscale,让自己的设备在外面也能访问文件和管理页。博客则要让读者点开链接就能看。我当时没有域名,就为网站单独用了 Cloudflare Quick Tunnel。家里的 Data 由 Samba 提供,给访客看的内容放在 HexoBlog/public。
一次发布从 Windows 出发:电脑把 Markdown 生成为 HTML、CSS 和图片,再经 SMB 把生成结果传给 NAS。一次阅读从访客浏览器出发:浏览器打开公开的 HTTPS 网址,Cloudflare 把请求交给 NAS 主动连出去的隧道。隧道在机器上只指向 127.0.0.1:17863,这个端口上的静态服务只读取 HexoBlog/public。这样,博客访问用不到 SMB、SSH 或 Cockpit 的端口,路由器也不需要为博客做入站端口映射。
首次启动,是在 Fedora 的 Cockpit 终端里,用有权写入 Data 的普通账号运行部署包里的脚本。
1 | bash /srv/nas/data/HexoBlog/start.sh |
脚本通过当前用户的 systemd 启动静态服务和 cloudflared。它先检查本机网页,再从公网回访核对站点标识,通过后才把网址写入 HexoBlog/blog-url.txt。所以刚运行时没看到这个文件,并不能说明博客已经坏了。要分辨卡在哪一步,可以在同一个 Fedora 用户会话里看日志。
1 | journalctl --user -u hexo-origin -u hexo-tunnel -n 40 --no-pager |
Quick Tunnel 给的是随机的 trycloudflare.com 地址,适合先把站跑起来。重新创建隧道可能换网址,更新文章则沿用当前隧道。 两件事分开之后,平时发文就很轻松。Cloudflare Quick Tunnels 官方说明
用 Hexo 写,用 Butterfly 展示
选博客程序时我考虑过 Halo,最后更喜欢 Butterfly 的文章卡片和阅读布局,就定了 Hexo 8.1.2 + 官方 Butterfly 5.7.0。Hexo 放在 Windows 上。Fedora 拿到的是已经生成的静态文件,电脑关机后,NAS 仍然可以继续响应读者。
主题装在 Hexo 项目的依赖里,Pug 和 Stylus 分别渲染模板和样式。当时用的是这组版本。
1 | npm install --save-exact hexo-theme-butterfly@5.7.0 hexo-renderer-pug@3.0.0 hexo-renderer-stylus@3.0.1 |
在 _config.yml 里设 theme: butterfly,然后在旁边的 _config.butterfly.yml 改主题配置。现在看到的暮色山湖、蓝蝶头像、副标题和侧栏都从这里配置。图标字体、封面和主题脚本随网页一起发布;换上主题以后,原来那篇开站手记也保留了原地址。上线时实际打开了电脑和手机宽度的页面,点过手机菜单、归档、标签和夜间模式。Butterfly 安装文档
这篇文章是怎么发出来的
现在再发一篇,只要在 Windows 项目的 blog/source/_posts/ 下面新建一个 UTF-8 的 .md 文件,写上标题、日期和正文,保存。双击项目里的 发布到NAS.cmd,或者在 blog 目录运行:
1 | npm run publish:nas |
这个命令先生成网站,把整套新文件复制到 NAS 的临时目录,复制成功才切换 public,并保留上一版。最后我会打开公网首页,点进新文章,核对标题、配图和正文。下一次修改一个错字也是同样的流程。Hexo 写作指南
这台机器现在有两种很具体的用法:要存一部影片,我打开 Windows 的 Data 共享;要分享一段文字,我写一份 Markdown,再把文章链接发出去。这篇搭建手记就是后一种用法。需要留在本地对照命令,也可以下载本文的 Markdown 原稿。
