如何解决为什么我的预构建云代工厂节点应用程序试图获取 node_modules 中已有的模块?
我有一个预先构建的节点应用程序,如果 npm install
在启动前运行,它不得尝试访问网络 - 目的是让所有内容都已经存在于 node_modules
目录中。它正在部署在云代工环境中。
这不是代理问题 - 在 Cloud Foundry 应用程序暂存期间不得尝试访问注册表 URL。我正在寻找它为什么要这样做的想法。
当这个应用被部署到 cloud Foundry 时,即使它在暂存期间检测到 node_modules
目录的存在,它仍然会尝试检索已经存在于 node_modules
中的基本依赖模块(如 @node/types) {1}},当然,尝试访问这些环境中不允许的注册表会超时。它不会尝试检索数百个其他依赖项,但出于某种原因,它认为它确实需要一些模块。例如:
2021-03-17T16:29:57.71-0700 [STG/0] OUT Installing any new modules (package.json + package-lock.json)
2021-03-17T16:32:31.78-0700 [STG/0] OUT npm ERR! code ECONNREFUSED
2021-03-17T16:32:31.78-0700 [STG/0] OUT npm ERR! errno ECONNREFUSED
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! FetchError: request to https://<registry-fqdn>/@types%2flong failed,reason: connect ECONNREFUSED 10.x.x.x:443
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at ClientRequest.<anonymous> (/tmp/contents784086672/deps/0/node/lib/node_modules/npm/node_modules/node-fetch-npm/src/index.js:68:14)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at ClientRequest.emit (events.js:315:20)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at TLSSocket.socketErrorListener (_http_client.js:469:9)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at TLSSocket.emit (events.js:315:20)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at emitErrorNT (internal/streams/destroy.js:106:8)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at emitErrorCloseNT (internal/streams/destroy.js:74:3)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at processTicksAndRejections (internal/process/task_queues.js:80:21)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! FetchError: request to https://<registry-fqdn>/@types%2flong failed,reason: connect ECONNREFUSED 10.x.x.x:443
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at ClientRequest.<anonymous> (/tmp/contents784086672/deps/0/node/lib/node_modules/npm/node_modules/node-fetch-npm/src/index.js:68:14)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at ClientRequest.emit (events.js:315:20)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at TLSSocket.socketErrorListener (_http_client.js:469:9)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at TLSSocket.emit (events.js:315:20)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at emitErrorNT (internal/streams/destroy.js:106:8)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at emitErrorCloseNT (internal/streams/destroy.js:74:3)
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! at processTicksAndRejections (internal/process/task_queues.js:80:21) {
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! type: 'system',2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! errno: 'ECONNREFUSED',2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! code: 'ECONNREFUSED',2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! parent: 'app'
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! }
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR!
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! If you are behind a proxy,please make sure that the
2021-03-17T16:32:31.79-0700 [STG/0] OUT npm ERR! 'proxy' config is set properly. See: 'npm help config'
2021-03-17T16:39:12.54-0700 [STG/0] OUT npm ERR! A complete log of this run can be found in:
2021-03-17T16:39:12.54-0700 [STG/0] OUT npm ERR! /home/vcap/.npm/_logs/2021-03-17T23_32_31_800Z-debug.log
2021-03-17T16:39:12.56-0700 [STG/0] OUT **ERROR** Unable to build dependencies: exit status 1
2021-03-17T16:39:13.07-0700 [STG/0] ERR Failed to compile droplet: Failed to run all supply scripts: exit status 14
2021-03-17T16:39:13.09-0700 [STG/0] OUT Exit status 223
2021-03-17T16:39:13.28-0700 [STG/0] OUT Cell 5cee670a-6f6c-4510-a274-5584f197038c stopping instance 59dda306-be2f-4d08-830c-77c08ffab3f5
2021-03-17T16:39:13.28-0700 [STG/0] OUT Cell 5cee670a-6f6c-4510-a274-5584f197038c destroying container for instance 59dda306-be2f-4d08-830c-77c08ffab3f5
2021-03-17T16:39:13.76-0700 [API/1] ERR Failed to stage build: staging failed
有什么想法吗?
编辑 #1 其他事实:
- 应用作为 zip 存档推送
- zip 文件系统包含
node_modules
目录,该目录由在“构建”期间运行的npm install
命令生成以构建 zip - zip 文件系统包括
package-lock.json
(来自源代码) - zip 存档中的任何位置都没有
.cfignore
文件 - zip 'build' 过去在 Windows 机器上进行,并且在随后推送到 cf 时没有此问题
- zip 'build' 最近从 k8s 集群迁移到 gitlab ci runner,该集群可能使用了 Centos 派生的映像
- 构建包版本为 1.7.32
- 构建机器上的 node (14.14.0) 版本与 buildpack 使用的版本匹配,但 npm 版本 (7.6.1) 不匹配(buildpack 使用 6.14.8)
- 将 zip 组装到 Ubuntu Bionic Beaver (18.04.4 LTS) 的构建映像更改为没有区别
解决方法
不能 100% 确定这会解决问题,但以下是我所看到的通常会导致尝试供应商 Node.js 依赖项的人:
首先,查看文档中的说明:https://docs.cloudfoundry.org/buildpacks/node/index.html#vendoring
- 运行
npm install
(你已经完成了) - 确保你有一个
package-lock.json
文件(你可能有这个)。这会锁定要使用的版本,并且应该保证node_modules/
中的内容与将安装的内容相匹配。如果你没有这个,你会看到来自 buildpack 的Warning: package-lock.json not found.
输出。 - 确保您推送了
package.json
、package-lock.json
和完整的node_modules/
目录以及所有应用程序代码。
这些没有被记录在案,但是我与其他人在这方面的工作中观察到的一些提示:
-
确保您没有
.cfignore
文件,因为这可能会意外导致node_modules/
不被推送。您通常可以判断node_modules/
是否没有被推送,因为这样推送的文件数量和大小会大得多。如果It is recommended to vendor the application's Node.js dependencies
目录不存在,您还会看到消息node_modules/
。 -
当您在本地运行
npm install
时,您需要在 Ubuntu Bionic VM 或容器中运行它。这是因为 NPM 经常会安装需要本机代码的模块。它会自动处理此问题,但node_modules/
中的内容特定于您运行npm install
的操作系统和架构。因此,如果您在非 Ubuntu 仿生操作系统(例如 Windows 或 MacOS)上运行npm install
,它将为您的本地机器编译本机代码。当你把它推上去时,它不会匹配,NPM 会尝试重新安装可以触发访问 Internet 的包。 -
确保您尽可能使用最新的 Node.js buildpack 和 Node.js 版本。拥有最新的代码并修复错误总是有帮助的。
-
NODE_ENV=production
将由 buildpack 设置,这有时会导致行为差异。它还跳过安装开发依赖项。不太可能是这里的问题,但值得一提,因为这会绊倒一些人。
事实证明,此问题是由生成 package-lock.json
文件的机器上的 npm 版本不匹配引起的,该机器填充了 node_modules
目录以包含在 zip 发行版 (npm v7.1) 中。 x),以及 Cloud Foundry 构建包使用的是什么 (npm v6.x)。
更改 dev 和 build 机器以使用 npm v6.x 生成 package-lock.json
文件并填充 node_modules
目录导致成功供应的 nodejs 应用程序。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。