为什么我的预构建 Cloud Foundry 节点应用程序试图获取已经在 node_modules 中的模块?
Why is my pre-built cloud foundry node app trying to fetch modules that are already in node_modules?
我有一个预构建的节点应用程序,如果 npm install
在启动之前是 运行,则该应用程序不得尝试访问网络 - 目的是让一切都已经存在于 node_modules
目录。它正在部署在 cloud foundry 环境中。
这不是代理问题 - 在 Cloud Foundry 应用暂存期间不得尝试访问注册表 url。我正在寻找它为什么要这样做的想法。
当此应用程序部署到 cloud foundry 时,即使它在暂存期间检测到 node_modules
目录的存在,它仍会尝试检索基本依赖模块(如 @node/types)已经出现在 node_modules
中,当然它会在尝试访问这些环境中不允许的注册表时超时。有数百个其他依赖项cies 没有尝试检索,但出于某种原因它认为它确实需要一些模块。例如:
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 运行ner,这可能使用了 centos 派生的图像
- buildpack 版本为 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/
是否未被推送,因为被推送的文件数量和大小将大大增加。如果 node_modules/
目录不存在,您还会看到消息 It is recommended to vendor the application's Node.js dependencies
。
当您在本地 运行 npm install
时,您需要将其 运行 连接到 Ubuntu 仿生虚拟机或容器中。这是因为 NPM 通常会安装需要本机代码的模块。它会自动处理这个问题,但是 node_modules/
中的内容是特定于 OS 和 运行 npm install
的架构的。因此,如果您在非 Ubuntu Bionic OS(例如 Windows 或 MacOS)上 运行 npm install
,它将编译本机代码对于您的本地机器。当你向上推送时,它不会匹配,NPM 将尝试重新安装可以触发访问 Internet 的包。
确保您使用的是最新的 Node.js 构建包和 Node.js 版本。拥有包含错误修复的最新代码总是有帮助的。
NODE_ENV=production
将由 buildpack 设置,这有时会导致行为差异。它还会跳过安装开发依赖项。不太可能是这里的问题,但值得一提,因为这会误导一些人。
这个问题原来是由生成 package-lock.json
文件的机器上的 npm 版本不匹配引起的,node_modules
目录被填充以包含在 zip 分发中的机器(npm v7.x),以及 cloud foundry 构建包使用的是什么 (npm v6.x)。
更改开发和构建机器以使用 npm v6.x 生成 package-lock.json
文件并填充 node_modules
目录导致成功销售 nodejs 应用程序。
我有一个预构建的节点应用程序,如果 npm install
在启动之前是 运行,则该应用程序不得尝试访问网络 - 目的是让一切都已经存在于 node_modules
目录。它正在部署在 cloud foundry 环境中。
这不是代理问题 - 在 Cloud Foundry 应用暂存期间不得尝试访问注册表 url。我正在寻找它为什么要这样做的想法。
当此应用程序部署到 cloud foundry 时,即使它在暂存期间检测到 node_modules
目录的存在,它仍会尝试检索基本依赖模块(如 @node/types)已经出现在 node_modules
中,当然它会在尝试访问这些环境中不允许的注册表时超时。有数百个其他依赖项cies 没有尝试检索,但出于某种原因它认为它确实需要一些模块。例如:
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 运行ner,这可能使用了 centos 派生的图像
- buildpack 版本为 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/
是否未被推送,因为被推送的文件数量和大小将大大增加。如果node_modules/
目录不存在,您还会看到消息It is recommended to vendor the application's Node.js dependencies
。当您在本地 运行
npm install
时,您需要将其 运行 连接到 Ubuntu 仿生虚拟机或容器中。这是因为 NPM 通常会安装需要本机代码的模块。它会自动处理这个问题,但是node_modules/
中的内容是特定于 OS 和 运行npm install
的架构的。因此,如果您在非 Ubuntu Bionic OS(例如 Windows 或 MacOS)上 运行npm install
,它将编译本机代码对于您的本地机器。当你向上推送时,它不会匹配,NPM 将尝试重新安装可以触发访问 Internet 的包。确保您使用的是最新的 Node.js 构建包和 Node.js 版本。拥有包含错误修复的最新代码总是有帮助的。
NODE_ENV=production
将由 buildpack 设置,这有时会导致行为差异。它还会跳过安装开发依赖项。不太可能是这里的问题,但值得一提,因为这会误导一些人。
这个问题原来是由生成 package-lock.json
文件的机器上的 npm 版本不匹配引起的,node_modules
目录被填充以包含在 zip 分发中的机器(npm v7.x),以及 cloud foundry 构建包使用的是什么 (npm v6.x)。
更改开发和构建机器以使用 npm v6.x 生成 package-lock.json
文件并填充 node_modules
目录导致成功销售 nodejs 应用程序。