【问题标题】:MongoNetworkError: failed to connect to server [mongodb:27017] on first connectMongoNetworkError:第一次连接时无法连接到服务器 [mongodb:27017]
【发布时间】:2021-02-16 16:45:13
【问题描述】:

我正在学习 docker 初学者课程 (https://www.youtube.com/watch?v=3c-iBn73dDE&t=4384s),我认为这门课程做得很好。

作为课程的一部分,应用程序与节点服务器和 js 前端组合在一起,与 docker 容器进行通信以实现 mongo db 和 mongo express 以实现持久性。

可以在https://gitlab.com/nanuchi/techworld-js-docker-demo-app/-/blob/master/app/server.js 找到节点应用程序。包含:

MongoClient.connect("mongodb://admin:password@mongodb:27017", 
function (err, client) {
if (err) throw err;

var db = client.db('user-account');
userObj['userid'] = 1;

我有 2 个 docker 容器在 chromebook 上的 ubuntu 20.04 上运行(屏幕截图)。当我跑步时:

11@penguin:~/techworld-js-docker-demo-app/app$ nodejs server.js 
 app listening on port 3000!

但是当我打开浏览器到 localhost:3000 时,我得到:

(node:2716) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring    pass option { useUnifiedTopology: true } to the MongoClient constructor.
/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/topologies/server.js:240
        throw err;
        ^

MongoNetworkError: failed to connect to server [mongodb:27017] on first connect [MongoNetworkError: getaddrinfo EAI_AGAIN mongodb mongodb:27017]
at Pool.<anonymous> (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/topologies/server.js:431:11)
at Pool.emit (events.js:198:13)
at createConnection (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/pool.js:559:14)
at connect (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/pool.js:973:11)
at makeConnection (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/connect.js:39:11)
at callback (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/connect.js:261:5)
at Socket.err (/home/11/techworld-js-docker-demo-app/app/node_modules/mongodb/lib/core/connection/connect.js:286:7)
at Object.onceWrapper (events.js:286:20)
at Socket.emit (events.js:198:13)
at emitErrorNT (internal/streams/destroy.js:91:8)

我做错了什么?

编辑;为了清楚起见,我正在我的本地机器上运行节点项目(从我的 ubuntu 主目录),并且我正在尝试连接到 docker mongo 容器作为后端。作者可能跳过了她想如何运行 gitlab 项目(否则我误解了),但我假设她想在主机上运行它。她可能计划在容器中运行它,但由于它是在 gitlab 而不是 docker 上,我不知道如何将节点项目放入容器中..

【问题讨论】:

  • 只是为了检查一下,您使用的是 mongo@3.6.x 吗?您可以通过运行mongo 进入 mongo shell 检查版本。
  • 运行 'docker exec -it 87ac1b2c5cad bash' 然后 mongo 我得到了 4.4.1 版
  • 你是如何启动你的mongodb实例的?看起来您正在尝试使用 docker 内部名称但从外部连接(在您的主机上运行的节点进程)

标签: node.js mongodb docker


【解决方案1】:

我认为您需要检查 Mongo URL "mongodb://admin:password@mongodb" 请参考以下示例 有连接MongoDB的例子

https://www.w3schools.com/nodejs/nodejs_mongodb_find.asp

这样试试

const mongoose = require('mongoose');
 let op = {
  poolSize: 10, 
  bufferMaxEntries: 0, 
  reconnectTries: 5000, 
  useNewUrlParser: true, 
  useCreateIndex: true, 
  useUnifiedTopology: true 
 }
    let db = await mongoose.connect(dbUrl + dbName, op)

【讨论】:

  • 我查看了这个并尝试了“mongodb://admin:password@mongodb:27017”,但失败了。你能告诉我更多细节吗
  • 请看上面的回答我已经更新了。
【解决方案2】:

/etc/mongod.conf 中的 net bindIp 值是什么?
(我不确定你的配置在哪里,但你可以试试vim /etc/mongod.conf

如果net bindIp为127.0.0.1,则只能连接localhost中的mongodb。
如下设置0.0.0.0,就可以在任何地方连接mongodb了。

# only localhost can connect 
net:
  port: 27017
  bindIp: 127.0.0.1

# everyone can connect 
net:
  port: 27017
  bindIp: 0.0.0.0

顺便说一下,修改配置后需要重启mongodb。

【讨论】:

    【解决方案3】:

    我刚刚在 Gitlab 中查看了您的项目。代码中的连接字符串设置为 mongodb 的 mongodb 主机名,当您同时运行节点进程和 docker 内的 mongodb 时,它应该可以正常工作。在您的问题中,您似乎正在从主机执行节点。这不允许解析 docker 内部主机名。要检查这一点,暂时使用localhost 而不是mongodb 作为主机名(使用此连接字符串mongodb://admin:password@localhost)。这将使用您的主机作为连接的目标,因为您还 mapped the ports in your docker-compose file 打开了主机上的端口。

    为了让您的代码在两种情况下都能正常工作(在主机上开发和用于产品的 all-in-docker),您不能在代码中对连接字符串进行硬编码,而是需要使其可配置。一种方法是为此使用环境变量。有关概念细节,请参阅the 12factor topic on configuration。当涉及到凭证时,这一点尤其重要,它根本不应该出现在 git 存储库中。因此,一种常见的做法是从环境中读取此类配置。使用节点,这就像阅读process.env.YOUR_VAR_FOR_MONGO_HOSTNAME 一样简单。详情请查看the node docs。然后这个变量需要exported 或传递给node 的调用。在这里提供一些便利的一个工具是包dotenv,它基本上允许在文本文件中指定环境以用于开发目的。然后,在您的 all-in-docker 设置中,您可以将环境变量相应地指定回 mongodb 而不是 localhost

    【讨论】:

    • 我在发布答案后看到了该编辑,但这正是我预期的情况。使用 localhost 作为 mongodb 主机名,只要您的 mongodb 像我引用的提交那样设置端口映射,您就可以使用本地节点进程。
    • 能否请您使用我在回答中推荐的连接字符串?我很确定这可以解决您的本地设置问题。如果没有,请告诉我。
    • 谢谢您,它现在可以工作了!我现在看到,基于gitlab.com/nanuchi/techworld-js-docker-demo-app/-/tree/master 自述文件,我应该使用“docker build -t my-app:1.0.”从 repo 构建一个图像。您通常在执行 docker build 之前 git clone 存储库吗?还是有另一种方法可以将远程仓库转换为本地 docker 镜像?
    • 太棒了!从技术上讲,如果有人将图像推送到 dockerhub,您可以按名称拉取它。但最好不要运行您不知道的图像。
    • 你能看看我的问题吗? stackoverflow.com/questions/71152255/…
    猜你喜欢
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 2017-05-10
    • 2021-12-30
    • 2022-07-27
    相关资源
    最近更新 更多