【问题标题】:Unable to connect the mongodb container to node container in docker无法将 mongodb 容器连接到 docker 中的节点容器
【发布时间】:2022-02-22 13:26:57
【问题描述】:

我从this repo 中的 2 个镜像和 1 个使用 MongoDB 公共镜像创建了 3 个 docker 容器。我使用sudo docker-compose -f docker-compose.yaml up打开了所有三个容器

docker-compose.yaml 是:

version: '3'
services:
  frontend:
    image: samar080301/mern-frontend:1.0
    ports:
      - 3000:3000
  backend:  
    image: samar080301/mern-backend:1.0
    ports:
      - 5000:5000
  mongodb:
    image: mongo:latest
    ports:
      - 27017:27017

但 MongoDB 无法连接节点服务器并报此错误:

backend_1   | > crud-app@1.0.0 start /home/app
backend_1   | > node server.js
backend_1   | 
backend_1   | (node:18) 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 engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
backend_1   | (Use `node --trace-deprecation ...` to show where the warning was created)
backend_1   | App running on port 5000
backend_1   | Error with the database! MongoNetworkError: failed to connect to server [localhost:27017] on first connect [Error: connect ECONNREFUSED 127.0.0.1:27017
backend_1   |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
backend_1   |   name: 'MongoNetworkError'
backend_1   | }]
backend_1   |     at Pool.<anonymous> (/home/app/node_modules/mongodb/lib/core/topologies/server.js:438:11)
backend_1   |     at Pool.emit (events.js:315:20)
backend_1   |     at /home/app/node_modules/mongodb/lib/core/connection/pool.js:562:14
backend_1   |     at /home/app/node_modules/mongodb/lib/core/connection/pool.js:995:11
backend_1   |     at /home/app/node_modules/mongodb/lib/core/connection/connect.js:32:7
backend_1   |     at callback (/home/app/node_modules/mongodb/lib/core/connection/connect.js:280:5)
backend_1   |     at Socket.<anonymous> (/home/app/node_modules/mongodb/lib/core/connection/connect.js:310:7)
backend_1   |     at Object.onceWrapper (events.js:422:26)
backend_1   |     at Socket.emit (events.js:315:20)
backend_1   |     at emitErrorNT (internal/streams/destroy.js:84:8)
backend_1   |     at processTicksAndRejections (internal/process/task_queues.js:84:21)
backend_1   | (node:18) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [Error: connect ECONNREFUSED 127.0.0.1:27017
backend_1   |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
backend_1   |   name: 'MongoNetworkError'
backend_1   | }]

backend/db.js的代码:

const mongoose = require('mongoose');
// Allow Promises
mongoose.Promise = global.Promise;
// Connection
mongoose.connect('mongodb://localhost:27017/db_test', { useNewUrlParser: true });
// Validation
mongoose.connection
  .once('open', () => console.log('Connected to the database!'))
  .on('error', err => console.log('Error with the database!', err));

docker inspect mongodb 的终端输出:

添加 mongo uri 作为环境变量后的终端输出:

backend_1   | App running on port 5000
backend_1   | (node:19) UnhandledPromiseRejectionWarning: MongooseError: The `uri` parameter to `openUri()` must be a string, got "undefined". Make sure the first parameter to `mongoose.connect()` or `mongoose.createConnection()` is a string.
backend_1   | (node:19) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)

新错误:

backend_1   | Error with the database! MongoNetworkError: failed to connect to server [merncrudapp_mongodb_1:27017] on first connect [Error: connect ECONNREFUSED 172.23.0.3:27017
backend_1   |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
backend_1   |   name: 'MongoNetworkError'
backend_1   | }]

【问题讨论】:

  • 请同时包含来自 mongodb 容器的日志。该错误表示它在后端连接到它时没有启动。这可能只是一个竞争条件,因为 mongo 需要一些时间来启动并开始监听端口。

标签: mongodb docker mongoose tcp ip


【解决方案1】:

尝试不使用localhost 而是使用容器名称进行连接。例如,如果你想从另一个容器(在同一个 docker 网络中)连接到 MongoDB,你可以使用mongodb:27017。 它应该可以工作。

【讨论】:

  • 我已经添加了DB连接的代码,我需要在那边改名字吗?
  • 是的,请尝试将localhost 替换为容器名称(在您的配置中为mongodb
  • 我做到了,它给了我这个错误Error with the database! { MongoNetworkError: failed to connect to server [mongodb:27017] on first connect [MongoNetworkError: getaddrinfo EAI_AGAIN mongodb mongodb:27017]
  • 我应该做 0.0.0.0:27017 吗?
  • 你的容器IP是172.20.0.3 :)
【解决方案2】:

当你运行 docker-compose up 时,happens:

  1. 创建了一个名为MernCrudApp(采用目录的默认名称)的网络。
  2. 使用frontend 的配置创建一个容器。它以frontend 的名义加入网络MernCrudApp
  3. 使用backend 的配置创建容器。它以backend 的名义加入网络MernCrudApp
  4. 使用mongodb 的配置创建一个容器。它以mongodb 的名义加入网络MernCrudApp

现在如果您使用mongodb://localhost:27017/db_test 连接到数据库,节点应用程序将在后端容器中查找 MongoDB,您将收到连接错误,因为它不存在。

要解决这个问题,请将 MongoDB 连接字符串更改为 mongodb://mongodb:27017/db_test,以便它

额外的 cmets
我会推荐以下内容,以帮助您解决使用当前配置将来可能遇到的一些问题。

  1. 将连接字符串添加为环境变量。这将使您在不重建容器的情况下更轻松地更改数据库实例。
  2. 由于后端应用程序依赖于数据库,在 docker-compose 文件中添加 depend_on 以便 MongoDB 容器在后端容器之前启动

【讨论】:

  • 如何将连接字符串添加为 env 变量?请告诉我,其实我刚开始学习docker
  • 假设 MONGO_URI 是 MongoDB 的环境变量。在 docker 文件 ENV MONGO_URI=mongodb://localhost:27017/db_test 中添加一行。一旦你构建它,你可以在 docker-compose 文件上改变它。查找有关此post的更多信息
  • 如何将该 uri 传递给我的 javascript 连接器代码?
  • example const mongo_uri = process.env.MONGO_URI 然后在使用mongodb连接函数时传递变量mongoose.connect(mongo_uri , { useNewUrlParser: true });
  • 我做到了,你可以在Github中查看更新的代码,我也更新了新的错误
【解决方案3】:

修改你的后端/db.js 代码。

您遇到错误是因为当您在代码中提及“localhost”时,您的容器正尝试连接到未使用的端口 2017 上的后端容器。

// Connection
//mongodb is a container name of mongo image
mongoose.connect('mongodb://mongodb:27017/db_test', { useNewUrlParser: true });

专业提示 - 1)如果您在同一个 docker 网络中,则使用主机名或 Docker 容器名称相互通信/链接。

2) 如果 IP 不是手动分配的,切勿在代码中使用容器 IP 地址。每当您重新启动容器时,它可能会发生变化。

【讨论】:

  • 我尝试了mongodb://merncrudapp_mongodb_1:27017/db_testmongodb://mongodb:27017/db_test。但他们都给了我错误,我在问题中添加了新错误
  • 你的 mongodb 容器在运行吗?从您的服务器检查此使用以下命令。命令 - telnet localhost 27017 如果您无法 telnet 27017 端口,则表示 Mongodb 容器未运行。
猜你喜欢
  • 1970-01-01
  • 2020-10-13
  • 2016-03-02
  • 2019-04-24
  • 2018-10-06
  • 2017-11-10
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多