如何实现Node.js+React monorepo自动部署至多台树莓派设备
多树莓派部署Node.js+React Monorepo自动更新落地方案
核心逻辑不用搞花里胡哨的,本质就是解决「main分支提交后自动出适配ARM的构建包」+「树莓派无人工干预完成版本替换」两个问题,按设备规模选对应方案就行,不用上来就搭很重的K8s之类的集群,树莓派性能够不上也没必要。
方案一:轻量拉取式(适合10-50台规模,运维成本几乎为0)
- CI触发规则直接绑main分支的push事件,触发后做跨架构构建:注意树莓派是ARM架构,别直接拿x86环境装的node_modules打包,要么用QEMU模拟ARM环境装依赖构建,要么安装依赖时指定
--target_arch=arm64(32位系统换armv7l),把Node服务代码、React构建后的静态文件、生产依赖一起打包成带git commit hash版本号的压缩包,同时生成一个存最新版本号、压缩包下载地址、文件sha256值的latest.json文件,两个文件直接丢你现有服务的静态目录下就行,不用单独搭文件服务。 - 每台树莓派上写个100行以内的Node或者shell守护脚本,用systemd托管设成开机自启:脚本每隔固定间隔(3-10分钟随便设)请求一次
latest.json,把返回的版本号和本地存的当前运行版本对比,发现版本不一致就走更新流程:- 给当前运行的应用发SIGTERM信号,等10秒让服务优雅退出,没退就强杀
- 先把当前正在运行的版本完整备份到本地单独目录
- 下载新版本压缩包,用返回的sha256值校验文件完整性,下载/校验失败直接终止流程等下一轮重试
- 把压缩包解压到临时目录,不要直接覆盖运行中的目录,解压完成后用软链接把应用运行目录切到新版本位置,做原子替换,避免中途断网搞坏文件
- 启动新版本服务,等15秒检查健康接口是否正常,正常就把本地版本号更新成最新版,不正常就直接切回之前备份的旧版本,写本地日志留排查记录
- Monorepo构建直接用你现有工作区的缓存能力(turbo/nx/pnpm都支持),只打包有代码变更的子包,压缩包体积能小很多,树莓派下载更快。
方案二:管控式推送架构(适合50台以上规模,需要可控更新节奏)
如果设备量上来了,怕全量更新出问题炸所有点位,就在轻量方案基础上加个极简的设备管控服务,不用买商业方案,自己写个几百行的服务就行,核心功能就三个:
- 维护设备列表:每个树莓派的守护进程启动后主动和服务建立WebSocket长连接,上报自己的设备ID、当前运行版本、所属分组(可以按点位分测试组、正式组)、在线状态
- 更新触发:CI构建完新版本包之后,先给测试组设备推更新指令,测试组跑半小时没问题,再按批次给正式组推,每批推完等一会看错误率,错多了就暂停回滚
- 状态可视化:简单做个页面能看每台设备的在线状态、当前版本、更新失败原因,不用逐台登上去查日志
设备端收到更新指令后的替换、校验、回滚逻辑和方案一完全一致,只是把定时轮询查版本改成了长连接收指令,更新更及时,也能控制节奏。
树莓派环境专属避坑点
- 别搞差量更新,树莓派的存储和性能够用,全量包替换逻辑最简单,出问题的概率比差量补丁低一个数量级
- 下载更新包的时候给每个设备加个0-300秒的随机延迟,别所有设备同一时间冲上来下包把出口带宽打满
- 守护脚本一定要设成崩溃自动重启,要是守护进程自己挂了,设备就收不到更新了
- 不要在更新脚本里硬编码写有写权限的密钥,所有更新包都走只读路径下载,避免单台设备被攻破之后影响整个代码仓库和所有设备
内容的提问来源于stack exchange,提问作者mtbossa
相关产品推荐
相关产品推荐

