ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

代码放在自己的 NAS:虚拟组网连接飞牛与 Ubuntu,搭建私有 Git 工作流

代码放在自己的 NAS:虚拟组网连接飞牛与 Ubuntu,搭建私有 Git 工作流 写过几个小项目以后我开始遇到一个问题代码散落在电脑和服务器上文件夹名字从“最新版”变成“最新版2”过一段时间就很难判断哪份才是正在运行的版本。NAS 有存储空间Ubuntu 能运行服务把两者连起来正好可以做一个自己的代码托管和部署练习。这次用飞牛 NAS 安装 Gitea保存一个私有 Git 仓库Ubuntu 通过星空组网克隆、修改并推送代码再从另一份工作目录拉取运行。最终得到一张能够打开的网页以及可以查到修改内容的提交记录。整个过程使用演示文件不需要把自己的正式项目搬进去。一、先弄清楚两台机器的分工Gitea 是代码托管服务Git 负责记录和传输版本星空组网负责让 Ubuntu 能通过虚拟 IP 找到 NAS。部署这一步仍然由我们执行创建仓库并不会自动把网页运行起来。可以把流程想成三个位置工作目录里写代码NAS 仓库里保存已推送的历史发布目录里放当前运行的文件。后两个目录不会随着编辑器里的保存动作一起改变因此我们需要明确执行推送和拉取。这个练习只用一个分支和一个页面先把版本流转跑通再考虑多人协作或自动部署。表中的 IP 是本次实际分配结果照做时要替换成自己的地址。飞牛初始化是在本地管理入口完成的截图中的后台操作与 Ubuntu 经组网访问分别验证。本文验收的是 Ubuntu 到 NAS 的 Git 路径不据此推断所有终端都能互通也不将连通成功等同于 P2P 直连。二、登录星空后台给设备准备独立成员从星空组网官网进入登录页使用自己的主账号登录。没有账号的读者可以先注册入口放在文末。账号、验证码和密码都自己填写截图只保留空登录表单及登录后的状态。进入“设备管理 → 成员列表”为 NAS 和 Ubuntu 分别准备一个成员。新建时填写便于识别的设备名称和成员名设置密码完成后复制完整成员账号供对应设备的客户端登录使用。主账号管理设备成员账号登录设备飞牛管理账号和 Gitea 账号则是另外两套身份不能混用。本次 Ubuntu 已有可用成员直接复用NAS 切换原生客户端后使用自己的成员。两端上线后先核对名称、在线状态和虚拟 IP。仅在后台看见成员还不够后面还要从 Ubuntu 发起实际请求。三、飞牛安装原生 FPK并确认连上网络先在飞牛系统设置中查看处理器架构。我的设备是 ARM所以从官方飞牛安装说明下载Stars-v6.1.0-arm64.fpk使用 x86 机器的读者应选择对应架构的软件包。打开“应用中心 → 手动安装”上传 FPK阅读应用信息与系统提示再按向导选择存储位置并完成安装。如果页面出现未经验证应用提示应先确认下载来源和包名理解提示后自行决定是否继续。安装结束在已安装列表中找到“星空组网”点击打开。这里有一个迁移时容易忽略的细节我的 NAS 原来运行过 Docker 版客户端。安装原生版前先停止旧容器并取消它的开机自动开启保留原容器与配置。两套客户端同时启动可能争用端口或产生难以判断的连接状态。以后重新应用旧 Compose 时还要留意原来的重启策略是否被恢复。在原生控制台登录 NAS 专用的完整成员账号连接后查看虚拟 IP 和运行状态。本次得到192.168.188.7/24状态显示已连接服务检查正常。旧容器曾使用的地址已经离线因此后面的仓库地址统一改用.7。Ubuntu 端本次已有原生客户端先核验再使用尚未安装的读者可按官方 Linux 说明安装并交互登录自己的成员账号。不要把密码写进命令行或项目文件。stars version sudo stars status ip -4 -brief address show StarVPN确认 Ubuntu 虚拟 IP 后再测试 NAS 的实际服务端口。能打开飞牛后台只能证明该端口可达Gitea 安装后还需检查它自己的3000端口。四、在飞牛部署 Gitea建立私有仓库在飞牛应用中心搜索 Gitea。本次页面显示版本为 1.27.1安装到存储空间1安装完成后打开初始化页面。这里使用的是飞牛应用中心提供的 Gitea 应用和前面下载的星空官方 FPK 是两个独立软件包。个人练习选择 SQLite3 即可数据库和仓库路径保留应用预填值避免还没开始就增加数据库维护工作。几个关键参数如下基础 URL 要填写 Ubuntu 能访问的地址末尾保留/。如果这里填成只在家里可达的局域网地址页面给出的克隆链接也可能把你带到错误的网络路径。Gitea 配置说明解释了ROOT_URL等参数的用途。我关闭了自助注册和 OpenID并要求登录后查看页面。展开管理员设置填写演示用户名nas-demo、邮箱及自己的密码点击“立即安装”后耐心等待不要反复提交。安装完成登录首页点击“创建仓库”仓库名填starvpn-nas-demo勾选“将仓库设为私有”默认分支保留main勾选初始化仓库以添加 README。这时仓库名称旁应有“私有库”标识。私有设置约束的是仓库访问权限不会自动给后面部署出来的网页增加登录功能。本次数据库实际位于/vol1/appdata/Gitea/data/gitea.db仓库根目录是/vol1/appdata/Gitea/data/gitea-repositories。这些是应用内部路径无须为了跟随文章去手动创建同名文件夹。若选择其他存储空间应以自己初始化页面显示的路径为准记录清楚即可。五、Ubuntu 克隆仓库写入第一版页面下面的命令在 Ubuntu 执行。先确认 Git、Python 和目标端口再创建独立目录。本文使用当前用户的家目录截图中登录用户是 root所以展开后位于/root。若目录已经存在换个新名字不要覆盖旧项目。git --version python3 --version ss -ltn ( sport :8090 ) curl --connect-timeout 5 --max-time 10 -I \ http://192.168.188.7:3000/ mkdir -m 700 ~/starvpn-nas-demo-20260909 cd ~/starvpn-nas-demo-20260909 git -c credential.helper clone \ http://nas-demo192.168.188.7:3000/nas-demo/starvpn-nas-demo.git work cd work git config user.name nas-demo git config user.email nas-demoexample.com git config credential.helper 出现 Password 提示时输入 Gitea 密码终端不回显字符属于正常现象。这里的user.name和user.email是提交署名认证仍由 Gitea 完成。配置没有加--global只影响当前仓库相关规则见 Git 配置文档。为方便连续演示我实际使用了专用的临时内存密码缓存结束后清除本文命令采用交互认证按提示输入即可。缓存如果报目录权限过宽应修正专用目录权限而不是改用明文密码文件。Git 缓存文档说明了它的内存保存和超时行为。创建public/index.html页面只需要说明项目来自哪里并显示一个可核对的版本号mkdir public cat public/index.html HTML !doctype html html langzh-CN meta charsetutf-8 meta nameviewport contentwidthdevice-width,initial-scale1 title我的 NAS 私有 Git 项目/title style body{max-width:760px;margin:12vh auto;padding:32px; font:20px/1.8 system-ui;background:#f4f7fb;color:#17283c} main{background:white;padding:40px;border-radius:16px} small{color:#2768b4}h1{line-height:1.35} /style main smallStarVPN · fnOS · Ubuntu/small h1代码在 NAS页面在 Ubuntu/h1 p通过星空组网从私有 Gitea 仓库拉取并部署。/p p当前版本strongv1/strong/p /main /html HTML git add public/index.html git commit -m feat: add private Git demo page v1 git push origin mainadd选择本次要记录的文件commit把它记入本地历史push才将提交发送到 NAS。执行完刷新 Gitea应该能看到public目录和新增提交仅仅出现本地提交成功并不代表远端已经收到。遇到失败时先看发生在哪一步。例如提交成功但推送超时本地版本仍然保留恢复连接后重新推送即可不必重新创建仓库。若终端提示没有需要提交的内容先查看git status确认修改的是当前工作目录中的文件而不是另一份发布副本。这个区分比反复点击重试更容易找到原因。六、拉取部署再通过第二版验证更新流程回到演示目录从 NAS 再克隆一份release。这一份用于运行work用于修改两者独立便于观察“推送之后还要拉取”这一步。cd ~/starvpn-nas-demo-20260909 git -c credential.helper clone \ http://nas-demo192.168.188.7:3000/nas-demo/starvpn-nas-demo.git release cd release git config credential.helper nohup python3 -m http.server 8090 --bind 192.168.188.5 \ --directory public ../http.log 21 echo $! ../http.pid curl --fail http://192.168.188.5:8090/--directory public把服务范围限定在网页目录仓库根部的.git不在里面--bind使用 Ubuntu 自己的组网 IP。这里采用 Python 标准库完成练习长期提供服务应另行配置正式 Web 服务和进程管理Python 官方文档也说明了它的适用限制。现在回到工作目录把v1改成v2检查差异再提交推送。以下替换脚本先确认目标文本出现一次避免在内容已经变化后误改。cd ~/starvpn-nas-demo-20260909/work python3 - PY from pathlib import Path p Path(public/index.html) s p.read_text(encodingutf-8) assert s.count(strongv1/strong) 1, 请检查当前版本 p.write_text(s.replace(strongv1/strong, strongv2/strong), encodingutf-8) PY git diff -- public/index.html git add public/index.html git commit -m docs: update demo page to v2 git push origin main cd ../release git pull --ff-only origin main git log -3 --oneline sha256sum ../work/public/index.html public/index.html curl --fail http://192.168.188.5:8090/使用--ff-only可以在发布目录出现分叉时停下来避免一次普通更新意外生成合并提交。正常情况下拉取会将页面推进到刚才推送的版本。两个文件的 SHA256 应相同浏览器刷新后也应显示v2静态文件更新不需要重启这次 Python 服务。提交记录可以帮助我们回答“这个版本改了什么”。打开 Gitea 的提交页找到更新到第二版的那条记录应只看到版本文字的变化。提交编号由实际内容和提交信息等因素决定照做时不必得到与截图相同的编号应该比较的是你自己工作目录、NAS 仓库和发布目录所指向的版本是否一致。在这里插入图片描述七、如何判断真的完成以及遇到问题先查哪里这次验证要同时看三处Gitea 收到提交发布目录拉取到同一版本HTTP 返回的页面包含新版本号。还应在未登录状态测试私有仓库确认没有凭据时不能读取代码。截图中的每个结果只证明对应环节后台“在线”不能替代 Git 和网页的实际请求。实测第二版提交为b437ee9两份页面的 SHA256 一致。未携带认证信息请求 Git 读取接口返回401页面返回200且包含v2从网页端口请求/.git/config返回404。浏览器也已通过 Ubuntu 的组网地址打开新版页面。演示不需要新增公网端口映射。网页本身没有认证组网内能够访问该端口的设备可以读取演示内容正式使用时应限制成员权限并按需要配置应用层 HTTPS 和访问控制。源码只保存在 NAS 也不等于完成备份仓库、数据库和 Gitea 配置都应纳入备份计划。还有一个容易混淆的地址是127.0.0.1它指向执行命令或打开浏览器的那台机器。Ubuntu 请求 NAS 时不能拿它代替 NAS 的虚拟 IP另一台电脑查看网页时也不能用它代替 Ubuntu。排查连接问题时先把“从哪台设备发起、访问哪个地址和端口”写清楚再检查对应的一段路径。本文运行的是便于理解的手动部署流程尚未验证整机重启后的自动恢复。练习结束如果要停止页面服务先用保存的 PID 核对进程再终止它避免误停其他 Python 项目cd ~/starvpn-nas-demo-20260909 ps -p $(cat http.pid) -o pid,args 确认输出是本次 8090 页面服务后执行 kill $(cat http.pid)完成这套流程后NAS 上留下可查看的项目历史Ubuntu 上运行的版本也有据可查。以后修改页面时沿着“检查差异、提交推送、拉取验证”的顺序操作就能知道代码改了什么以及服务器实际运行了哪一版。注册星空组网
返回列表