我在Windows上使用Docker桌面应用程序. 在Ubuntu WSL2中,我有一个停靠容器,其中运行着一个Meteor/NodeJS服务器. 从WSL内部通过Docker-Compose启动.

docker-compose.yaml
  ...
  environment:
    - ROOT_URL=http://localhost:8080
    - PORT=8080
  ports:
    - "8080:8080"

调用服务器上的Meteor-Files,它将执行以下请求:

  return new Promise((resolve, reject) => {
    UserFiles.load(url, options,
      (loadError, fileRef) => {
        if (loadError) {
          return reject(loadError);
        } else {
          return resolve(fileRef);
        }
      }, true);
  });
}

现在,停靠容器中的应用程序必须访问其自身的一个HTTP端点,如http://127.0.0.1:8080/api

当我从outside调用docker中的this端点时,我得到了正确的结果.

当我使用终端连接到 docker 容器并curl 端点时,我得到了正确的结果.

Update:在真正的Linux机器上运行Docker,而不是在Windows上运行WSL2 Ubuntu时,它也能正常工作.

但是,当在容器中运行的应用程序/服务try 使用相同的URL通过相同的端点调用自己时,我得到了一个ECONNREFUSED - CONNECTION REFUSED错误.

完整错误消息:

FetchError: request to http://127.0.0.1:8080/api failed, reason: connect ECONNREFUSED 127.0.0.1:8080
at ClientRequest.<anonymous> (/app/bundle/programs/server/npm/node_modules/meteor/fetch/node_modules/node-fetch/lib/index.js:1444:11)
at ClientRequest.emit (events.js:315:20)
at ClientRequest.EventEmitter.emit (domain.js:483:12)
at Socket.socketErrorListener (_http_client.js:426:9)
at Socket.emit (events.js:315:20)
at Socket.EventEmitter.emit (domain.js:483:12)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
 => awaited here:
     at Function.Promise.await (/app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/promise_server.js:56:12)
     at imports/startup/filemigration.js:273:20
     at /app/bundle/programs/server/npm/node_modules/meteor/promise/node_modules/meteor-promise/fiber_pool.js:43:40 {
   type: 'system',
   errno: 'ECONNREFUSED',
   code: 'ECONNREFUSED'
 }

这会有什么问题呢?也许是WSL2的安全问题?

推荐答案

根据错误消息,最终需要访问应用程序本身的HTTP端点的代码驻留在一个名为:imports/startup/filemigration.js的文件中

从它的名字来看,我认为它是在应用程序启动时运行的.然而,有一种可能性是,Meteor应用程序还没有启动其http node 服务器,因此出现了"连接被拒绝"的错误消息.

甚至在不同的启动任务之间可能存在竞争条件,从而根据具体的环境导致不同的行为.

如果可行,您可以try 稍微推迟启动/迁移任务,以确保Meteor应用程序已正确启动其服务器并侦听端口.

为此,您通常可以使用Meteor.startup(func):

在启动客户端或服务器时运行[Func]代码.

[.]

在服务器上,该函数将在服务器进程完成启动后立即运行.

Node.js相关问答推荐

node 无法验证第一个证书

使用Vite和ReactJS时,在哪里设置NODE_OPTIONS?

使用HTTPS从NodeJS 17.9.1升级到18.0.0后,SignalR连接失败

GitLab SAST中的Nodejcan未找到匹配项

Node.js PNG缓冲区获取未知图像格式错误

使用单个 MongoDB 查询更新多个元素

MongoDB:通过匹配输入字符串或输入字符串中的单个单词进行搜索

我需要聚合两个 MongoDB 集合

将 null 推入管道后,node.js 可写完成未发出

使用更新版本仍然找到包@angular/fire但不支持原理图

如何在套接字对象中存储或添加数据?

如何在mongoose 聚合中执行全文搜索

Nodejs 从链接数组中获取数据并保存到 mongodb

在 Node JS 中使用 url 链接而不是文件路径

BrowserRouter 无法渲染组件

无法关闭 node.js 中的mongoose 连接

使用 Forms API 进行批量更新时生成 itemId

如何在 NodeJs 中下载和解压缩内存中的 zip 文件?

node.js 中存储的模块变量在什么范围内?

Mongoose:模式与模型?