
1. 项目概述这到底是个什么东西先说结论vue-xiuxiangame是一个基于 Vue.js 开发的文字修仙类网页游戏纯前端项目不需要复杂的后端服务跑起来就是个网页。你要做的就是把构建好的静态文件扔到 NAS 上通过 Web 服务托管起来然后浏览器手机电脑都行打开就能玩。为什么要拿 NAS 来跑这种小项目我个人的理解有这么几层第一NAS 的定位本来就是家里那台永远不关机的服务器。文字修仙这类放置挂机游戏核心玩法就是挂机涨经验你不需要一直盯着屏幕它自己在那儿跑。这种游戏放在一台 7x24 小时开机的设备上天然合适。你要是开着自己的电脑挂机且不说费电风扇噪音和发热也够你烦的而 NAS 本来就在那儿 24 小时干活顺手托管一个网页游戏毫无压力。第二飞牛 fnOS 的 Docker 生态比想象中成熟。我玩过群晖、威联通、绿联也折腾过各种 DIY NAS 系统。飞牛fnOS虽然是新面孔但它的应用中心集成了 Docker 管理界面支持 docker-composeUI 做得也顺手这对不熟悉命令行的朋友非常友好。所以这篇文章我会覆盖两种姿势纯界面操作和SSH 命令行操作大家按自己习惯来。第三文字修仙类游戏非常适合上班摸鱼这个场景。页面是静态的、加载快、不需要登录复杂的账号体系玩起来就是点点按钮看看文字不显眼。浏览器直接打开、关闭也不留痕迹没有客户端进程。往深了说这个摸鱼行为本质上是在自己搭建的服务上自娱自乐既不占用公司带宽看视频也不安装任何插件软件就是访问一个网页而已。所以这套方案的受众很明确有 NAS 但不知道除了存文件还能干嘛的朋友想在公司/单位里找个正经理由偷闲的上班族对 Docker 部署有兴趣、想拿小项目练手的新手这篇文章我会从零开始带你走完整个部署链路包括项目文件获取、构建镜像、配置反代、内网穿透如果有需要、数据备份以及我踩过的坑。2. 部署前的环境检查与思路梳理动手之前先把账算清楚部署这件事最怕闷头就干结果环境不匹配搞到心态炸裂。我把需要确认的事项列一下。2.1 确认你的飞牛设备处于可用状态不管你是 x86 小主机刷的飞牛还是 ARM 板子装的 fnOS第一步都是一样的——确认 Docker 服务正常。飞牛 fnOS 的系统设置里能找到 Docker 相关的入口。如果用的是应用中心装的 Docker 插件记得看一下运行状态。我之前碰到过一次飞牛系统更新后 Docker 服务没自动拉起的情况现象是 Docker 管理界面能打开但所有容器状态显示异常。解决办法很简单SSH 进去执行sudo systemctl restart docker正常情况下重启完就好了。如果还不行去飞牛的应用商店里把 Docker 应用先停用再启用也基本能解决。另外确认一下设备的 CPU 架构。飞牛官方对 x86 设备的兼容性最好但市面上也有不少 ARM 架构的盒子刷了 fnOS。架构不同Docker 镜像的选择会不一样后面构建的时候要特别留意。uname -m输出x86_64就选 amd64 的镜像输出aarch64就得选 arm64 的镜像。2.2 理解 vue-xiuxiangame 项目的运行原理vue-xiuxiangame 本质上是 Vue 2 或 Vue 3 的项目具体看你在 GitHub 拉到的分支版本它依赖 npm/yarn 之类的工具进行依赖安装和构建最终产出的是dist静态目录里面是打包压缩后的 HTML、JS、CSS。关键点在于它需要一个 Web 服务器来托管这些静态文件并且涉及前端路由。如果你用的是 history 模式的路由那么 Web 服务器必须配置好 fallback 规则否则刷新页面会 404。这个细节后面会讲到。部署方案无非两种本地构建后扔静态文件到 Nginx适合想自己掌控构建过程的玩家。Docker 镜像一把梭构建镜像时把项目代码编进去Docker 容器里跑 Nginx 托管静态文件管理起来更顺手。考虑到 NAS 上 Docker 是常态我会重点讲第二种但第一种也会顺带提一下因为有些朋友可能不想为了一个小游戏在 NAS 上多跑容器。2.3 准备工具清单部署前我习惯把所有要用的工具先列出来避免做到一半发现缺东西工具/资源用途获取方式vue-xiuxiangame 源码构建项目GitHub/Gitee 拉取Node.js 环境本地构建或 Docker 内构建官网或容器镜像Docker运行容器飞牛应用中心安装终端工具SSH命令行管理飞牛PuTTY / Termius / 系统自带终端文本编辑器修改配置VS Code / Notepad一个好用的浏览器访问和管理Chrome / Edge设备上没有现成 Node.js 环境的也别慌Docker 容器里可以临时跑 Node 镜像来构建构建完删除即可不需要污染宿主机。3. 核心细节解析项目架构与部署关键技术3.1 vue-xiuxiangame 的项目结构拆解把这项目扒开看看有助于理解后面每一步操作的含义。拿到的源码通常包含这些关键目录和文件vue-xiuxiangame/ ├── public/ # 静态公共资源 ├── src/ # 源码目录 │ ├── components/ # 组件 │ ├── views/ # 页面视图 │ ├── router/ # 路由配置 │ ├── store/ # 状态管理 │ ├── utils/ # 工具函数 │ └── App.vue # 根组件 ├── package.json # 项目依赖配置 ├── vite.config.js # Vite 构建配置如果用的是 Vite └── Dockerfile # 可能自带 Docker 部署配置其中package.json最重要它定义了项目的构建命令和依赖版本。一般来说你要关注这几个字段scripts.build生产构建命令通常是npm run buildscripts.dev本地开发启动命令通常npm run devdependencies和devDependencies依赖列表构建时靠它们装包我第一次看到这项目时就觉得代码量不大几千行的单页 Vue 应用把修仙小说里的修炼体系、灵根、功法这些概念用简单的文字加数字模拟出来逻辑比较直白适合拿来当练手项目。3.2 路由模式为什么刷新会 404Vue SPA 应用的路由有两种模式hash 模式URL 长这样/#/home刷新永远没问题因为#后面的内容不会发给服务器。history 模式URL 长这样/home好看但刷新时浏览器会向服务器请求/home这个路径如果你的 Web 服务器没有 fallback 规则就会返回 404。vue-xiuxiangame 具体用的哪种模式取决于源码里router/index.js的配置。我建议在部署前先把这个文件打开看一眼const router new VueRouter({ mode: history, // 或者 mode: hash routes: [...] })如果是history模式Nginx 配置里必须加上location / { try_files $uri $uri/ /index.html; }这一行意思很直白浏览器访问的路径如果找不到对应文件就把请求转给index.html然后由前端路由接管。我印象中 vue-xiuxiangame 默认应该是 hash 模式但不同 fork 版本可能不同所以还是自己看一眼最稳妥。如果不想看代码也可以部署之后故意刷新一下非首页的路径如果 404 了就知道是 history 模式的问题了。3.3 镜像选择与数据持久化的设计在飞牛上跑 Docker通常需要关心的有两件事镜像用谁的、数据存哪里。vue-xiuxiangame 的数据逻辑很简单游戏进度一般存在浏览器的 localStorage 里这意味着容器本身几乎不产生数据文件不需要挂载数据卷。但如果你希望存档能够定期备份或者想换个浏览器也能继承进度那就得考虑把 localStorage 的备份导出来。这个后面我会单独说。镜像方面如果项目没有自带 Dockerfile那我们就自己写一个极简的FROM node:16-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:alpine COPY --frombuilder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD [nginx, -g, daemon off;]这个镜像的构建过程分两阶段第一阶段用 Node 镜像装依赖并构建产出dist目录。第二阶段用 Nginx 镜像把dist目录里的静态文件拷进去。好处是最终的镜像里只有构建产物和 Nginx干干净净体积小不会把 Node 相关的包带进去。如果你拿到项目自带 Dockerfile那就更省事了直接 build 就行。4. 实操过程在飞牛 NAS 上从零完成部署现在进入正题拿一台已经装好 fnOS 的设备按部就班走一遍完整的部署流程。我会把常用的两种方式都写出来用飞牛的 Docker 界面和SSH 命令行。两种方式任选其一即可结果是一样。4.1 获取项目源码先把 vue-xiuxiangame 项目弄到手。通常在 GitHub 上搜索就能找到仓库国内网络环境下也可以找 Gitee 上的镜像仓库。# 在飞牛的某个目录下创建项目文件夹比如 /vol1/docker/xiuxian cd /vol1/docker/xiuxian git clone https://github.com/你的仓库地址/vue-xiuxiangame.git如果你没有配 git 相关的加速或代理clone 可能会比较慢甚至有超时风险。这时候有两个路子直接去 GitHub 页面下载 ZIP 压缩包然后上传到飞牛上解压。在 Gitee 上搜索该项目gitee 在国内访问速度快很多。我一般习惯直接在飞牛下载 ZIP 再解压省得在 SSH 里等半天。解压完确认目录结构ls -la vue-xiuxiangame/如果你看到package.json和src说明源码完整。4.2 方法一Docker 命令行部署推荐可复现性最强飞牛 fnOS 底层是 Debian 内核SSH 进去就是标准的 Linux 环境。Docker 仓库有现成的构建工具链先把工作目录准备好cd /vol1/docker/xiuxian写一个DockerfileFROM node:16-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm install --registryhttps://registry.npmmirror.com COPY . . RUN npm run build FROM nginx:alpine COPY --frombuilder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD [nginx, -g, daemon off;]这里我故意把 npm 的 registry 换成了阿里镜像因为国内服务器/设备直接访问 npm 官方源很慢这是构建过程能不能顺利过的一个关键点。再写一个nginx.confserver { listen 80; server_name _; root /usr/share/nginx/html; index index.html; location / { try_files $uri $uri/ /index.html; } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires 7d; add_header Cache-Control public, immutable; } }为了兼顾 history 模式下刷新不 404try_files那行必不可少。缓存规则是额外的加分项刷页面的时候加载更快。构建镜像docker build -t vue-xiuxiangame:latest .构建完成后跑容器docker run -d \ --name vue-xiuxiangame \ --restart unless-stopped \ -p 8080:80 \ vue-xiuxiangame:latest参数说明-d后台运行-p 8080:80宿主机的 8080 端口映射到容器内的 80 端口。这里我选了 8080你也可以换成别的未被占用的端口比如 9527、8081 等--restart unless-stoppedNAS 重启后容器自动拉起这个参数对长期运行的设备非常关键--name容器命名方便管理启动完执行docker ps看看容器状态是 Up 就说明成功了。浏览器访问http://NAS的IP:8080就能看到游戏界面。4.3 方法二飞牛 Docker 管理界面操作如果你不太习惯命令行飞牛的 Web 管理界面也完全可以完成上述步骤但有一点需要提前说明——飞牛的 Docker 界面更擅长管理现成镜像对本地构建这种操作支持有限。所以用界面操作的话我建议换成另一条路找一个现成的 Web 服务器镜像比如nginx然后把构建好的项目文件传进容器里。步骤一在飞牛应用中心安装 Docker如果还没有装的话 步骤二打开 Docker 管理界面在镜像页面里搜索nginx拉取nginx:alpine镜像 步骤三创建容器时把端口映射成宿主机的某个端口 步骤四进入容器终端或者在镜像的 Web 管理工具里上传文件到/usr/share/nginx/html。这种方式比较繁琐的地方在于文件上传需要先把构建好的dist目录打包再一个个传进容器。如果你不会本地构建也可以在飞牛的另一个临时容器里跑构建流程然后再复制产物。但说实话既然都到这一步了直接用命令行反而更省事。所以我给纯界面操作的朋友的建议是能接受命令行就用命令行不能接受就用 docker-compose这个飞牛界面是支持的配置好几个环境变量就能拉起服务。4.4 docker-compose 方式推荐长期运行既然要在 NAS 上长期跑我推荐用 docker-compose 的方式管理升级和备份都更方便。在项目目录里写一个docker-compose.ymlversion: 3 services: vue-xiuxiangame: build: . image: vue-xiuxiangame:latest container_name: vue-xiuxiangame restart: unless-stopped ports: - 8080:80启动docker-compose up -d如果后期源码更新了rebuild 一下就行docker-compose build docker-compose up -d注意飞牛系统里如果没有安装 docker-compose 插件但支持 compose 命令时会输出docker compose子命令的方式你用docker compose up -d也行效果一样看你环境支持哪种写法。4.5 验证部署并开始游戏容器起来后回到飞牛管理界面找到容器的日志看看有没有报错或者直接用浏览器访问http://192.168.1.100:8080把192.168.1.100替换成你自己的 NAS 内网 IP。第一次点进去你会看到这个游戏的主界面通常包括角色面板、修炼按钮、背包、任务列表、突破境界的进度条之类。整体风格偏文字复古但逻辑完整玩起来莫名上头。如果打不开优先检查三件事端口有没有映射对8080:80表示访问 8080容器内是 80防火墙有没有拦截端口飞牛默认防火墙一般不会拦内网流量但如果你开了安全策略要手动放行容器的状态是不是 Exited日志里看报错4.6 上班摸鱼的进阶配置外网访问在办公室摸鱼访问的自然是外网的地址你不能在电脑上输内网 IP。如果你家里有公网 IP用 DDNS 绑定域名是最稳的方案如果没公网 IP就得走内网穿透。飞牛系统自带了 DDNS 的功能可以绑定花生壳、阿里云等 DNS 服务商。配置好之后你在外网访问的地址是http://yourdomain.com:8080这里有两个坑我得提醒你坑一运营商封了 80 端口。国内大部分家庭宽带的 80 端口是被封的所以你映射到宿主机时别用 80 端口用 8080 之类的非常规端口这样被扫描的概率小很多也能正常走 HTTP 访问。坑二动态公网 IP 会变。今天的 IP 和明天的可能不一样只靠 DDNS 还不够配合容器自动重启的--restart unless-stopped参数即使 NAS 断网重启服务也能自动恢复。如果你没有公网 IP那就只能走内网穿透工具了。常见的方案是 frp、Tailscale、ZeroTier。在飞牛上跑这些工具也很简单容器化一键拉起。我个人更推荐 Tailscale配置极简装好之后设备之间组一个虚拟局域网办公室电脑装个客户端直接访问家里 NAS 的内网地址相当于把自己设备搬进了家。这样连端口映射都省了数据也是加密的安全性比裸奔的 DDNS 高很多。5. 常见问题与排查技巧实录部署过程中十有八九会遇到这样那样的报错我这里把我自己踩过的几次坑整理成速查表每一条都是实战过的。现象可能原因解决方案浏览器打开页面显示 404Nginx 没有配置try_filesfallback 规则在 Nginx 配置中添加try_files $uri $uri/ /index.html;重载配置构建时 npm install 卡住或超时网络问题或 npm 官方源缓慢更换 npm 镜像源为https://registry.npmmirror.comDocker 拉取镜像超时网络原因配置 Docker 镜像加速器给 /etc/docker/daemon.json 添加 registry-mirrors容器启动后马上退出镜像结构问题或 Nginx 配置错误用docker logs查看容器日志逐行排查页面能打开但所有按钮无反应JS 文件加载失败或浏览器缓存了旧版本强制刷新 CtrlF5检查控制台网络请求是否有报错手机浏览器能玩但 PC 打不开端口封装时只绑定了特定协议确认映射协议同时包含 TCP/UDP或只映射 TCP 即可存档莫名其妙丢失浏览器 localStorage 被清理定期导出存档字符串保存在 NAS 本地系统重启后容器没自动恢复没有配置 restart 策略更新容器加上--restart unless-stopped5.1 构建阶段的典型报错构建 Vue 项目最常见的报错就是npm ERR! code ENOENT或者各种版本不匹配多数情况是 Node 版本太新或太旧。npm 的版本兼容性问题很烦解决方案就一条锁版本。在package.json的engines字段里写清楚要求的 Node 版本然后 Dockerfile 里用对应版本的 Node 镜像构建。比如项目是 Vue 2 老项目Node 16 比较稳Vue 3 Vite 的项目Node 16 也基本够用Node 18/20 兼容性更好一些。如果构建时代码报错说某个语法不支持通常是 Node 版本太老。还有一种情况是项目代码有 bug比如依赖不完整、某个模块缺失。这种情况别硬调先看错误信息里的文件名和行号多半能猜出是哪个依赖没装全。在 Dockerfile 里以RUN npm install代替RUN npm ci可以避免 package-lock.json 与实际版本不一致导致的安装失败。5.2 运行阶段的网络排查部署好了但是怎么都访问不了这种问题最让人头大。我总结了套路化的排查顺序从最外层往最里层检查容器是否活着docker ps -a看状态是否为 Up。如果是 Exiteddocker logs看报错。检查端口监听netstat -tlnp | grep 8080确认端口被 Docker 代理监听。检查防火墙飞牛默认对来自局域网内的访问一般是放行的但如果开启了高级安全策略手动添加规则放行 8080。检查宿主机到容器的联通curl http://localhost:8080看看容器内的服务是否正常响应。检查局域网其他设备换个设备、换个浏览器测试排除浏览器缓存或插件干扰。如果到最后一步还是不行多半是网络环境的问题比如路由器开了 AP 隔离、VLAN 没互通之类的这就不在 NAS 的层面上了。5.3 存档备份防止修为清空惨剧前面说过这个游戏的存档放在浏览器 localStorage 里这意味着存档跟着浏览器走不跟着服务器走。你要是换电脑、换浏览器登录同一个地址进度是从头开始的。这本身不算部署问题但从管理和备份的角度讲要提个醒平时玩的时候养成定期导出存档的习惯。游戏里一般会有导出存档按钮或者你可以在浏览器开发者工具的 Application 标签页里手动复制 localStorage 内容。把导出的存档文件存一份到 NAS 的共享文件夹里相当于给游戏进度做备份。如果你在公司摸鱼建议清空浏览器记录前先导出存档别问我是怎么知道的……5.4 如何让你的游戏页面更好看、更好用一个后端都配好了前端还能不能进一步折腾提升体验能。PWA 离线缓存如果项目支持 PWA渐进式 Web 应用可以在飞牛环境里配一个 Service Worker把页面资源缓存到本地。这样即使公司网络波动游戏也能正常打开。纯前端要实现这个不复杂但要看项目本身有没有引入相关插件没有就得改源码加插件。自定义域名和 HTTPS如果你有自己的域名可以用 Nginx 反向代理 8080 端口然后配置 SSL 证书实现 HTTPS 访问。一是更安全传输过程不裸奔二是浏览器地址栏没有不安全的红色警告摸鱼更从容。桌面图标快捷方式电脑上可以用 Chrome 的创建快捷方式功能把网页游戏变成一个独立的窗口看起来像个原生应用没有地址栏更隐蔽。手机上可以用 Safari 的添加到主屏幕效果也一样。这一点对摸鱼党来说简直是刚需。6. 选型对比为什么不直接用官方的 Demo 站点聊完了部署细节我来解释一下为什么费这个劲在 NAS 上自部署而不是直接玩网上现成的文字修仙游戏。市面上的文字修仙网页游戏不少很多都有公开的 Demo 地址注册就能玩。但这类共享站点的痛点很明显存档不受你控制、服务器随时可能停服、数据说不清哪天就没了。而自己 NAS 上部署一份是完全私有的环境游戏进度存在你自己的设备上想备份就备份想清空就清空没有任何心理负担。而且自部署的好处不只是拥有数据你还能改代码。开源的 vue-xiuxiangame你完全可以自己修改数值、添加玩法、调整界面文字把它变成你的专属版本。这个自由度是任何在线 Demo 都给不了的。从技术角度讲用 NAS 跑一个前端静态项目也是了解 Docker、Nginx、内网穿透这些基础运维概念的绝佳练手场景。很多东西你光看教程是不行的真正操作一遍、踩一遍坑才记得住。7. 一点个人经验总结最后分享几点我多次部署类似项目后的体会给飞牛等 NAS 系统的 Docker 部署流程建立一套标准动作。我用下来最顺手的一套流程是项目源码放一个固定目录 → 项目里写 Dockerfile 和 docker-compose.yml → 构建运行 → 数据目录单独挂载。以后每一个新项目都按这个套路走省心很多。注意飞牛的面板权限问题。飞牛 Web 面板创建的文件默认属主可能不是 root有时候在 SSH 里访问项目目录会遇到权限不足。遇到permission denied别硬刚用sudo chown -R改一下目录属主就行。不要小看日志。Docker 容器挂了docker logs里的报错信息就是救命稻草。养成看日志的习惯比到处问人高效十倍。很多时候一个 Nginx 配置少了个分号启动时不会报错但访问时 404这种问题看日志马上就定位到了。做好备份策略。不只是游戏存档Docker 的容器配置、docker-compose 文件、Nginx 配置全都要定期打包备份。飞牛有快照功能重要目录打个快照出问题一秒回滚。我用这个功能救回过一次手残删掉的容器配置强烈推荐。整个过程跑下来你会发现在 NAS 上部署一个网页游戏这件事本质上就是在家里搭建一个小型 Web 服务。今天的载体是文字修仙游戏明天换个项目比如个人博客、笔记系统、下载工具、智能家居面板套路完全一样。把底层逻辑摸透了以后再部署什么新东西都是熟门熟路的事。