使用Docker的MongoDB"第一次连接失败,无法连接到服务器[localhost:27017]"。

31

我正在使用MongoDB和NodeJS后端。问题是我遇到以下错误:

node:16) UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]

这是我的docker-compose文件

version: '3.4'

services:
  db:
    image: mongo:latest
    ports:
      - '27017:27017'

  rest-api-node:
    build: .
    ports:
      - '5000:5000'
    links:
      - db
    restart: on-failure

我已经尝试了depends_on,但是没有起作用。

在后端,我使用mongoose作为中间件与数据库进行通信。这是我的index.js的一部分。

mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost/demo')
app.listen(port, () => console.log("live"))

我也尝试过使用 Promise,但没有改变。请帮帮我。谢谢。

完整的错误日志

在 Pool. (/app/node_modules/mongodb-core/lib/topologies/server.js:505:11) rest-api-node_1 | 在 Pool.emit (events.js:180:13) rest-api-node_1 | 在 Connection. (/app/node_modules/mongodb-core/lib/connection/pool.js:329:12) rest-api-node_1 | 在 Object.onceWrapper (events.js:272:13) rest-api-node_1 | 在 Connection.emit (events.js:180:13) rest-api-node_1 | 在 Socket. (/app/node_modules/mongodb-core/lib/connection/connection.js:245:50) rest-api-node_1 | 在 Object.onceWrapper (events.js:272:13) rest-api-node_1 | 在 Socket.emit (events.js:180:13) rest-api-node_1 | 在 emitErrorNT (internal/streams/destroy.js:64:8) rest-api-node_1 | 在 process._tickCallback (internal/process/next_tick.js:178:19) rest-api-node_1 | name: 'MongoNetworkError', rest-api-node_1 |
message: 'failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017]' }

6个回答

61

默认情况下,Compose会为您的应用程序设置一个单独的网络。每个服务的容器都加入了默认网络,并且可以通过该网络上的其他容器进行访问和发现,发现时使用的主机名与容器名称相同。

根据您的docker-compose.yaml文件,您只能从主机机器上访问mongo容器的127.0.0.1:27017。为了从NodeJS后端容器访问它,您应该使用db:27017


2
“db:27017” 是什么意思? - Jim Kim
3
我认为问题出在Mongo URL上。我曾经遇到过同样的问题。容器内部没有localhost。你必须将URL更改为mongodb://db:27017/demo。这解决了我的问题。 - Rajesh Barik
1
错误:Compose文件'./docker-compose.yml'无效,因为: services.mongo.ports无效:端口“db:27017”无效,应该是[[remote_ip:]remote_port[-remote_port]:]port[/protocol] - 上述建议导致此错误。我还尝试了我正在使用的数据库名称。 - ChumiestBucket
4
为什么你要给那个回答投-1呢?你不需要修改上面的docker-compose.yml文件,因为当你修改它后就会出现错误。我的帖子是关于应用程序设置的,其中我们定义了到mongodb容器的url。应该是'db:27017'而不是'localhost:27017'。 - nickgryg
1
如果你的docker-compose有用户名和密码,那么这要如何工作? - user11800286
显示剩余3条评论

20

我有同样的问题,其他解决方案对我没有用,但我是这样做的

注意:

对于Mongo URI,您必须使用您的MongoDB 服务名称而不是127.0.0.1localhost

例如,在下面的docker-compose文件中,我的mongo服务名称是mongodb-myapp,我将URI更改为mongodb://mongodb-myapp:27017/myapp,这对我有效。


services:
  boilerplate-api-app:
    build: .
    environment:
      - MONGO_URI=mongodb://mongodb-myapp:27017/myapp
    volumes:
      - .:/app
    ports:
      - "5000:5000"
    depends_on:
      - mongodb-myapp

 mongodb-myapp:
    image: mongo
    ports:
      - "27017:27017"

2

docker-compose.yaml

version: "3"
services:
  node-app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - PORT=3000
  mongo:
    image: mongo
    environment:
      - MONGO_INITDB_ROOT_USERNAME=imran
      - MONGO_INITDB_ROOT_PASSWORD=test_password
    volumes:
      - mongo-db:/data/db

volumes:
  mongo-db:

以上代码是docker-compose.yaml文件,MongoDB的服务名称为“mongo”。您不必手动插入容器的IP地址。相反,只需在MongoDB URI中插入服务名称,如下面给出的示例代码:
const express = require("express");
const mongoose = require("mongoose");

const app = express();
mongoose
  .connect("mongodb://imran:test_password@mongo:27017/?authSource=admin")
  .then(() => {
    console.log("Successfully connected to the DB");
  })
  .catch((e) => {
    console.log(e);
  });

const port = process.env.PORT || 3000;

// routes
app.get("/", (req, res) => {
  res.send("<h1>Running on Container!</h1>");
});

app.listen(port, () => console.log(`listening on port ${port}`));

1
我也被这个问题困扰了好几个小时!在连接字符串中设置db:27017,并在rest-api-node上设置restart: always,可以确保您连接到正确的IP,并确保节点服务器不断尝试连接到您的数据库。对我来说有效!

0

我通过在mongosh中使用命令db.runCommand({whatsmyuri: 1})来检查我的本地mongodb的IP并使用那个IP解决了它。


0

我遇到了这个问题,因为MongoDB已经在本地运行(而不是在Docker上),使用了不同的凭据,并且这具有优先于在Docker上运行的数据库。

在这种情况下,解决方案要么是终止本地MongoDB,要么是更改端口:

  ports:
    - "27018:27017"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接