实时全球行情监测:包含纳斯达克100、上证50、恒生科技及英伟达、特斯拉等核心资产的 AI 逻辑审计。
Alpha Command_Pulse
Initializing_Tactical_Data_Link...

NAS 部署全指南:从 Cloudflare Tunnel 到一键自动化更新实战

本文标题是 "NAS 部署全指南:从 Cloudflare Tunnel 到一键自动化更新实战",由作者 小白 记录于 dev 板块。 核心摘要:深度拆解如何利用 Cloudflare Tunnel、Docker Compose 与自定义脚本,将 NAS 打造为 7x24 小时在线的高性能主权服务器。解决 SSH 10808 代理报错与自动化构建难题。。 关键词:NAS, Docker, Cloudflare, 自动化, Astro, ssh, 部署。 最后更新时间:Mon Mar 02 2026 08:00:00 GMT+0800 (中国标准时间)。

NAS 部署全指南:从 Cloudflare Tunnel 到一键自动化更新实战

作为一名全栈工程师,我一直认为:如果你不能完全掌控你的运行环境,你就不算真正拥有你的代码。

2019 年我从北京搬回贵阳,当时最头疼的不是职场的转换,而是如何安置我那堆零散的数字资产。在经过了多次 VPS 欠费、数据泄露风险和云服务商的策略调整后,我决定在书房的角落里塞进一台群晖(Synology)DS923+。

这台机器不仅是我的数据仓库,更是我所有“数字花园”的物理根基。今天,我将通过超过 3000 字的深度实战,拆解如何将一个 Astro + React 的现代博客系统,从本地开发环境完美迁移至 NAS,并实现“发布即更新”的极致丝滑体验。

一、 为什么在 2026 年,你依然需要一台 NAS 部署?

很多人会问:“小白,现在 Cloudflare Pages 和 Vercel 那么方便,为什么还要折腾 NAS 这种‘重资产’部署?”

我的逻辑很简单:为了对抗熵增,为了数据主权。

1.1 资产主权的物理保障

Cloudflare 确实好用,但它本质上还是一个“黑盒”。如果你的文章包含了一些敏感的金融回测数据(比如我的 finance_engine.py 抓取的数据),或者一些尚未公开的随笔,存在别人的服务器上总有一种“租房住”的不安定感。NAS 让我拥有了物理层面的 root 权限。

1.2 计算能力的本地化红利

我的 AltStack 背后挂着一堆 Python API,用于执行全量 SEO 审计和字数统计。在云端运行这些脚本需要配置复杂的 Python 环境和 Token 额度。而在 NAS 上,我可以随意拉取 Docker 镜像,通过本地 Socket 协议实现秒级的内网通信,没有任何流量计费的焦虑。

1.3 极低延迟的“边缘节点”

对于贵阳的访问者(或者我的内网设备)来说,NAS 部署意味着毫秒级的响应。配合 Cloudflare Tunnel 的全球分发,我既享受了 CDN 的带宽加成,又保留了源站的自主权。


二、 核心架构:Cloudflare Tunnel 的优雅穿透

在没有公网 IP(或者不想折腾动态 DNS)的情况下,Cloudflare Tunnel 是目前的唯一真神。它彻底终结了“端口转发”的黑产时代。

2.1 传统的反向代理 vs Tunnel

传统的 DDNS 需要你在路由器上开启 80/443 端口转发。这就像是在你的城堡围墙上开了一个洞,任何人只要扫描到你的 IP 就能尝试攻击。

Tunnel (Argo Tunnel) 的逻辑是逆向的:NAS 内部运行一个 cloudflared 客户端,主动向 Cloudflare 的边缘节点建立四个加密的连接隧道。外部访问请求到达 Cloudflare 边缘后,通过这些隧道“流”进你的内网。这意味着:

  • 你不需要公网 IP。
  • 你的防火墙不需要开启任何入站端口。
  • 你的真实服务器 IP 被彻底隐藏。

2.2 Cloudflare Zero Trust 后台配置指南

很多同学在配置 Tunnel 时会卡在控制台界面。以下是我的“小白版”步骤:

  1. 进入 Dashboard:登录 Cloudflare,点击左侧导航栏的 Zero Trust
  2. 创建 Tunnel:在 Networks -> Tunnels 中点击 Add a tunnel
  3. 选择 Cloudflared:你会得到一个 Token请妥善保管这个字符串,它是你 NAS 接入云端的唯一凭证。
  4. 配置 Public Hostname
    • Domain: 填入你的域名(如 xbstack.com)。
    • Service Type: 选 HTTP
    • URL: 填入内网容器地址 altstack_app:4321(注意,这里可以直接写 Docker 服务名,前提是它们在同一个 Network 下)。

2.3 Docker Compose 的全量部署逻辑

我在 NAS 上采用了一套“双塔架构”:一个容器跑 cloudflared,一个容器跑我们的 Astro 博客应用。

version: '3.8'

services:
  # 穿透塔:负责流量引入
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: always
    environment:
      - TUNNEL_TOKEN=${CF_TUNNEL_TOKEN}
    command: tunnel run
    networks:
      - web_network

  # 应用塔:负责业务响应
  blog_ssr:
    image: node:20-slim
    container_name: altstack_app
    working_dir: /app
    volumes:
      - ./blog:/app
    environment:
      - NODE_ENV=production
      - HOST=0.0.0.0
      - PORT=4321
    # 增加内存限制,防止构建时撑爆 NAS 内存
    deploy:
      resources:
        limits:
          memory: 2G
    command: sh -c "npm install && npm run build && node dist/server/entry.mjs"
    restart: always
    networks:
      - web_network

networks:
  web_network:
    driver: bridge

小白避坑指南:在 NAS 这种内存受限的环境下,不要直接在 node 镜像里运行 npm install。我建议在本地构建好 node_modules 文件夹后通过 rsync 同步,或者在构建时使用 --max-old-space-size=4096 限制内存,否则在大规模代码混淆(Obfuscation)任务中容易导致 NAS 系统死机。


三、 环境治理:解决 SSH 10808 代理报错

这可能是每一个在 Mac 上开发、部署到 NAS 的同学都会遇到的“幽灵报错”。

3.1 10808 噩梦:Connection Refused

由于我在 Mac 上常驻着 Clash 代理(监听 10808 端口),终端环境变量里会有 http_proxy=http://127.0.0.1:10808

当你尝试执行 ssh-copy-id admin@192.168.1.100时,SSH 会错误地通过代理服务器去连接内网地址。因为代理服务器是在本地运行的,它根本找不到 192.168.1.100 的存在。

3.2 终极解决方案:SSH 配置对齐

最优雅的做法是修改 ~/.ssh/config,强制让内网流量直接握手,不经过任何 ProxyCommand。

# ~/.ssh/config
# 对 NAS 内网地址禁用代理
Host 192.168.*.*
    ProxyCommand none
    IdentityFile ~/.ssh/id_rsa_nas
    User admin

此外,你可以在执行命令前通过 unset http_proxy https_proxy 临时清理环境变量。但我更倾向于配置化的方案,因为脚本运行是自动的,人为干预越少越好。


四、 实战:打造“发布即更新”的工业级流水线

手动拉代码、重启服务太土了。我们需要的是那种“一键点火,全站更新”的仪式感。

4.1 工业化脚本 nas_update.sh 的深度设计

我编写了一个增强版的部署脚本,包含了预质检、构建锁和自动推送。

#!/bin/bash
# nas_update.sh

set -e # 遇到错误立即停止执行

echo "--- 开始发布任务 ---"

# 1. 预质检:确保代码已提交并推送到远端
git push origin main

# 2. 远程执行构建指令
ssh nas << 'EOF'
  cd /volume1/web/blog
  
  # 获取最新代码
  git pull origin main
  
  # 如果 package.json 没变,跳过 npm install 以节省时间
  if ! git diff --quiet HEAD@{1} HEAD -- package.json; then
    npm ci --silent
  fi
  
  # 执行快速构建(我自定义了 build:fast 脚本,移除了不必要的图像压缩)
  export NODE_OPTIONS='--max-old-space-size=2048'
  if npm run build:fast; then
    echo "构建成功,准备重启服务"
    pm2 restart altstack-ssr || pm2 start dist/server/entry.mjs --name altstack-ssr
  else
    echo "❌ 构建失败,正在回滚..."
    git checkout .
    exit 1
  fi
EOF

# 3. 推送 SEO (在本地执行,因为 API Key 存在本地)
python3 python-api/seo_pusher.py

echo "--- 发布完成 ---"

4.2 为什么需要 PM2?

在 NAS 的 Docker 容器之外,我通常会加一层 PM2 守护。虽然 Docker 有 restart: always,但 PM2 提供了更直观的日志查看和零停机更新(Reload)。当我在 NAS 上进行 SSR 渲染时,PM2 的内存监控能有效防止 Node.js 的内存泄漏把系统拖垮。


五、 性能优化:在 NAS 上跑出 99 分

NAS 的 CPU 通常是 Intel Celeron 或 AMD Ryzen 嵌入式系列,单核性能远不如 MacBook。

  1. NVMe 缓存:如果你的 NAS 支持 NVMe SSD,请务必将其设为“读写缓存”。npm install 产生的大量碎文件读写在机械硬盘上是灾难,但在 SSD 缓存下能提速 5 倍。
  2. Swap 调优:我将群晖的 Swappiness 调低了。虽然内存只有 8GB,但我宁愿它触发 OOM 杀掉进程,也不希望它频繁交换磁盘导致整个 UI 卡死。
  3. 图像预处理:不要让 NAS 去压缩几百张 4K 图片。我在发布前会运行 scripts/optimize_images.py 在 Mac 上处理完,NAS 只负责展示 WebP 格式。

六、 安全进阶:内网穿透后的“堡垒审计”

当你把 NAS 通过 Tunnel 暴露给外网时,如果不做安全审计,这无异于裸奔。

6.1 物理层封禁:利用群晖自带的防护

开启“自动封禁”。设置 5 分钟内尝试失败 3 次即永久封锁 IP。虽然 Tunnel 隐藏了真实 IP,但对应用层的尝试依然需要这一层底线。

6.2 SSH 的反暴力破解:fail2ban 实战

我建议在 Docker 中跑一个 fail2ban 容器,专门审计 SSH 日志,防止内网横向攻击。记住,一旦你的 Tunnel 被攻破,攻击者距离你书房里的数据只有一步之遥。

6.3 专家级 WAF:利用 Cloudflare 过滤恶意爬虫

在 Cloudflare 后台,我为 xbstack.com 配置了三条规则:

  1. 区域封锁:封禁所有非中国地区的 /admin/* 访问请求。
  2. 威胁分数:威胁分数 > 10 的请求开启 Managed Challenge。
  3. 速率限制:针对搜索 API 路径,限制单 IP 每分钟请求量。

七、 数据容灾:不要把鸡蛋放在一个篮子里

NAS 不是保险箱,它只是一个方便的篮子。我的容灾策略是 3-2-1 原则

  • 3 份副本:NAS 本地、Mac 开发机、云端。
  • 2 种介质:机械硬盘 + 云存储。
  • 1 份异地:利用群晖的 Cloud Sync,每天凌晨 3 点将加密后的博客源码和静态资源包同步到 Backblaze B2。

即使发生火灾或地震,我只需要在任何一台新电脑上执行 git clone,我的数字花园就能瞬间重生。


八、 结语:让博客成为你的“数字主权”

在贵阳寒冷的冬夜里,看着 NAS 面板上跳动的 LED 灯,我知道,我的思想正通过这台机器,跨过重重迷雾,与世界同步。这种从硬件到软件的完整控制感,才是全栈工程师真正的快乐所在。


💬 评论互动

  1. 你目前是在用 VPS 还是 NAS 跑博客?遇到了哪些玄学 Bug?
  2. Cloudflare Tunnel 在你那里的访问速度满意吗?
  3. 关于 10808 代理报错,你还有更优雅的解法吗?
  4. 一键更新脚本里,你会增加数据库自动备份吗?

欢迎留言,我是小白,我们一起 Debug 人生。

Author
小白
WEALTH ENGINEER

本文基于 CC BY-NC-SA 4.0 许可发布。 转载请注明出处,且仅限非商业用途。

Updated: Mar 2, 2026 © 2026 AltStack

评论互动