【问题标题】:How to create a self-updating Node.js application?如何创建一个自我更新的 Node.js 应用程序?
【发布时间】:2012-12-09 23:54:07
【问题描述】:

我想用 Node.js 创建一个应用程序,它会定期检查更新并安装它们(如果有的话)。

基本组件我很清楚:

  • 包含更新包的 Web 服务器(或 FTP 服务器、文件系统等)
  • 一个版本系统(例如 SemVer),以便您知道哪个包更新
  • 用于签署更新包的公钥算法

那么,何时检查更新和安装更新可能会有不同的策略:

  • 在应用程序启动时
  • 在应用程序端
  • 空闲时

应用程序甚至可能被硬关闭并自动重新启动。

但还有一些问题:

  • npm 上是否有任何模块已经提供了这样的系统?
  • 如何组织文件系统中的不同版本?基本上你会有一个主机和多个(版本化)核心。是否应该为所有这些设置一个 data 文件夹?
  • 如何处理npm install & co.对于新下载的包?
  • 如何处理损坏的更新?
  • 您如何实现这样的东西以使其与 Heroku & co. 兼容。哪里没有可以开车去的永久驱动器?

总的来说:您将如何尝试实现这样的系统?

【问题讨论】:

  • 当然,保持向后兼容是我的责任……但问题仍然存在:您将如何做这样的事情?
  • @GoloRoden 您最终采用了什么解决方案?我有类似的要求。发送
  • 不幸的是,我还没有最终找到解决方案,我们仍在调查想法...... :-(
  • @GoloRoden 现在呢?你的问题已经 5 年了:-)
  • 哈哈,情况和以前一样;-)

标签: node.js versioning auto-update self-updating


【解决方案1】:

首先,您可以使用 NPM 本身进行包和应用交付。其次,您可以添加脚本文件以在 package.json 文件中添加 cron 作业(例如“postinstall”或“update”)以进行定期更新过程。在此脚本中,您可以检查您需要的所有内容,例如损坏的更新。在 Heroku 中,您可以使用 Scheduler Worker 进行更新处理。

【讨论】:

    【解决方案2】:

    所以你的意思是你需要更新你的部署 版本控制,可以在更新中断时恢复。它还必须能够使用安全源进行更新,并且必须是 与 Heroku & co 兼容吗?

    唷,这要求太多了。

    听起来你想要像 Docker 这样的东西。 https://www.docker.com/

    与 Heroku 一起使用: https://devcenter.heroku.com/articles/container-registry-and-runtime

    那么 Docker 是什么? 简单来说,它就像 github,但用于部署。它不是对源代码的版本控制,而是对整个环境的版本控制。所以你可以让你的脚本在 Windows 上的 Ubuntu 环境中运行。它可以使用特定版本的 node.js。然后使用已经安装的一组特定的 NPM 依赖项。在构建所有这些层之后,它可以在该环境中使用您的应用程序的特定版本。您可以完全控制部署映像中包含的所有内容,并且它可以在 docker 运行的所有操作系统上运行(包括 heroku)。 (请注意,您不能使用 Windows 环境,除非在另一台装有 Docker 的 Windows 机器上)

    因此,使用 Docker,您无需让脚本运行 npm 更新,而是在开发版本上运行 npm install 并在测试后推送到您的 Docker 映像。然后,您的部署服务器可以在您的 Docker 映像上运行拉取以更新应用程序、所有依赖项,甚至操作系统更新,以确保它按预期运行。如果更新中断了安装,那么您可以恢复使用较早的 Docker 映像,就像您可以从 github 删除提交一样,您可以删除对映像的拉取然后运行它,就好像更新从未发生过一样。如果需要,您甚至可以通过创建新的映像构建来生成具有不同环境和版本的多个 Docker 实例。

    好的,这样就可以处理您的部署版本控制。呸!

    但是自动检查更新和检测损坏的安装等呢?

    您仍然需要构建一个更新程序脚本来获得您想要的那种行为您不能指望更新程序工具知道如何调试您的安装并确定它是否“损坏”或不是。也许您的脚本旨在引发错误。第三方更新程序脚本如何能够充分理解您的应用程序,从而确定是否需要回滚?

    因此,您的更新程序脚本应该管理 Docker 镜像的拉取和恢复。它可以在启动应用程序之前运行拉后测试。如果您希望它能够自我修复,您还应该确保您的应用程序能够处理错误。也就是说,由您的应用程序决定是否需要执行回滚。 Docker 使您的主应用程序可以(通过它的版本控制系统)与更新程序通信需要回滚。然后,您的更新程序脚本会在您的主应用退出后执行回滚到最后一个已知良好的 Docker 映像(并且可能在下一个版本发布之前不会再次执行拉取)。

    仅举几个用例示例:

    • 1。安全更新:

    您创建一个包含您的程序的 Docker 映像。你拥有了它 在 Ubuntu 16.04 环境中运行。它包含所有需要的 NPM 安装和节点 8。您上传到 Docker 存储库服务器。你 然后将映像部署到另一台机器并在那里运行。您的 应用程序现在正在用完另一个上的 Docker 容器 机器。

    稍后,您在 dev 构建中更新 NPM 包并发布一个 在线将新映像添加到您的 Docker 存储库。您的生产服务器 检测到新构建,关闭应用程序,执行拉取 更新它的本地 Docker 映像,并启动 应用程序再次使用它的本地 Docker 映像。你的申请 由于所需 NPM 模块的某些新版本而开始崩溃 打破一切。它处理错误,在 20 个错误之后 返回时,它会向更新程序脚本发出信号以执行回滚并 退出。由于您的应用程序关闭,Docker 容器将关闭。这 updater 脚本现在从本地映像中删除最后一个 Docker 拉取并 使用恢复的图像再次重新生成应用程序图像的实例。任何一种 对图像中的数据文件造成的损坏消失了。也许更新者也写 JSON文件的错误版本号,因此它可以跟踪什么 版本不执行拉动。您的应用程序现在正在运行 快乐如蛤蜊。

    但不满足于有一个损坏的版本并想要你的 其他包更新,您解决错误并恢复 NPM 导致开发版本出现问题的软件包。你推 更改您的在线 Docker 存储库并增加版本 数字。您的应用程序检测到新的 docker 构建,检查以确保它不是“禁止构建”,然后向更新程序发出信号以运行拉取,优雅地退出。这 Docker 实例结束,更新程序执行新的拉取。这次 周围,​​一切都很好,工作正常,所以不需要回滚。

    • 2。使用多个版本

    但现在让我们稍后再说,你真的是在猛烈抨击你的 应用程序,您已经向它添加了各种出色的功能。 它现在的能力提高了 5000%,但速度也降低了 5000%。如果你有 之前发布了一个简单的应用程序“版本 1”, 但是速度很快,并且它可以完成您在另一台服务器上进行某些部署所需的操作,那么它非常容易 只是从你的 Docker 中生成该确切版本的实例 存储库。如果您需要更高版本,请生成它。或者可能会在各地的 20 台不同的机器上产生各种各样的版本。无需预先设置,无需安装节点或 NPM 包等依赖项。无需从源代码构建东西或检查以确保所需的特定工具与此版本的 MacOSX 或 windows 或某种 linux 兼容。无需查看某个新版本的模块是否会破坏您的应用程序的早期版本。该应用程序将始终在 Ubuntu 16.04 环境中运行,其中包含当时适用的所有必需软件。如果有人真的想更新环境的某些方面,他们可以创建一个分支。

    【讨论】:

      【解决方案3】:

      不需要网络服务器。 Git 是托管公共和私有代码的完美解决方案,包括版本控制。对于私有存储库,您可以使用个人访问令牌。

      我创建了一个模块,用于从 git 存储库自动更新 node.js 应用程序。它将本地 package.json 与您的 repo 中的进行比较,然后自动克隆 repo 并安装依赖项。您可以将您的应用配置为在应用开始、结束或安排例行检查时检查更新。

      自动 Git 更新 - https://github.com/chegele/AutoGitUpdate

      import AutoGitUpdate from 'auto-git-update';
      
      const config = {
          repository: 'https://github.com/chegele/BackupPurger'
          tempLocation: 'C:/Users/scheg/Desktop/tmp/',
          ignoreFiles: ['util/config.js'],
          executeOnComplete: 'C:\\Users\\scheg\\Desktop\\worksapce\\AutoGitUpdate\\startTest.bat',
          exitOnComplete: true
      }
      
      const updater = new AutoGitUpdate(config);
      
      updater.autoUpdate();
      

      【讨论】:

        【解决方案4】:

        如果您使用的是 PM2,这是一种非常流行的方法,现在使用 node.js 扩展和运行应用程序。 然后你可能想看看他们提供的工具。 如: https://github.com/keymetrics/pm2-auto-pull

        【讨论】:

          猜你喜欢
          • 2021-05-08
          • 2019-03-07
          • 2016-10-20
          • 2016-11-22
          • 1970-01-01
          • 1970-01-01
          • 2011-02-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多