NestJs / Mongoose 在 Docker 撰写时无法建立 MongoDB 数据库连接

Posted

技术标签:

【中文标题】NestJs / Mongoose 在 Docker 撰写时无法建立 MongoDB 数据库连接【英文标题】:NestJs / Mongoose cannot make MongoDB database connection while on Docker compose 【发布时间】:2021-04-11 15:54:51 【问题描述】:

在运行我的前端、后端和 mongo 实例的 docker-compose 时,后端无法连接到 mongo db 容器。

我在后端使用 Mongoose 和 NestJs,连接代码如下所示:

const mongoUser = process.env.MONGO_USER;
const mongoPassword = process.env.MONGO_PASSWORD;
const mongoHostname = process.env.MONGO_HOSTNAME;
const mongoPort = process.env.MONGO_PORT;


const url = `mongodb://$mongoUser:$mongoPassword@$mongoHostname:$mongoPort`;

@Module(
  imports: [MongooseModule.forRoot(url, 
    useNewUrlParser: true,
    "user": process.env.MONGO_USER,
    "pass": process.env.MONGO_PASSWORD....

相应的 docker-compose.yaml 部分如下所示:

  backend:
    container_name: backend
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - 4001:4001
    depends_on:
      - mongo
    links:
      - mongo
    environment:
      MONGO_USER: root
      MONGO_PASSWORD: example
      MONGO_HOSTNAME: mongo
      MONGO_PORT: 27017
      PORT: 4001
    command: npm run start:dev

  mongo:
    image: mongo
    restart: always
    ports:
     - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

在容器的日志中,我可以看到正在尝试连接,但身份验证失败。

这里是日志。这很奇怪,因为环境端口工作并将其指向数据库,但显然 mongoDB 无法识别用户名和密码。

backend          | [Nest] 34   - 01/05/2021, 9:09:49 PM   [InstanceLoader] JwtModule dependencies initialized +1ms
mongo_1          | "t":"$date":"2021-01-05T21:09:49.815+00:00","s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":"remote":"172.18.0.5:47566","connectionId":4,"connectionCount":3
mongo_1          | "t":"$date":"2021-01-05T21:09:49.847+00:00","s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn4","msg":"client metadata","attr":"remote":"172.18.0.5:47566","client":"conn4","doc":"driver":"name":"nodejs|Mongoose","version":"3.6.3","os":"type":"Linux","name":"linux","architecture":"x64","version":"4.19.76-linuxkit","platform":"'Node.js v14.15.4, LE (unified)","version":"3.6.3|5.11.9"
mongo_1          | "t":"$date":"2021-01-05T21:09:49.856+00:00","s":"I",  "c":"NETWORK",  "id":22943,   "ctx":"listener","msg":"Connection accepted","attr":"remote":"172.18.0.5:47568","connectionId":5,"connectionCount":4
mongo_1          | "t":"$date":"2021-01-05T21:09:49.876+00:00","s":"I",  "c":"NETWORK",  "id":51800,   "ctx":"conn5","msg":"client metadata","attr":"remote":"172.18.0.5:47568","client":"conn5","doc":"driver":"name":"nodejs|Mongoose","version":"3.6.3","os":"type":"Linux","name":"linux","architecture":"x64","version":"4.19.76-linuxkit","platform":"'Node.js v14.15.4, LE (unified)","version":"3.6.3|5.11.9"
mongo_1          | "t":"$date":"2021-01-05T21:09:49.877+00:00","s":"I",  "c":"ACCESS",   "id":20251,   "ctx":"conn5","msg":"Supported SASL mechanisms requested for unknown user","attr":"user":"undefined@admin"
mongo_1          | "t":"$date":"2021-01-05T21:09:49.877+00:00","s":"I",  "c":"ACCESS",   "id":20249,   "ctx":"conn5","msg":"Authentication failed","attr":"mechanism":"SCRAM-SHA-256","principalName":"undefined","authenticationDatabase":"admin","client":"172.18.0.5:47568","result":"UserNotFound: Could not find user \"undefined\" for db \"admin\""
mongo_1          | "t":"$date":"2021-01-05T21:09:49.880+00:00","s":"I",  "c":"ACCESS",   "id":20249,   "ctx":"conn5","msg":"Authentication failed","attr":"mechanism":"SCRAM-SHA-1","principalName":"undefined","authenticationDatabase":"admin","client":"172.18.0.5:47568","result":"UserNotFound: Could not find user \"undefined\" for db \"admin\""
mongo_1          | "t":"$date":"2021-01-05T21:09:49.883+00:00","s":"I",  "c":"NETWORK",  "id":22944,   "ctx":"conn4","msg":"Connection ended","attr":"remote":"172.18.0.5:47566","connectionId":4,"connectionCount":3
backend          | [Nest] 34   - 01/05/2021, 9:09:49 PM   [MongooseModule] Unable to connect to the database. Retrying (1)... +73ms

【问题讨论】:

【参考方案1】:

我美化了mongo的JSON输出,发现UserNotFound: Could not find user \"undefined\" for db \"admin\"


  "t": 
    "$date": "2021-01-05T21:09:49.877+00:00"
  ,
  "s": "I",
  "c": "ACCESS",
  "id": 20251,
  "ctx": "conn5",
  "msg": "Supported SASL mechanisms requested for unknown user",
  "attr": 
    "user": "undefined@admin"
  
 
  "t": 
    "$date": "2021-01-05T21:09:49.877+00:00"
  ,
  "s": "I",
  "c": "ACCESS",
  "id": 20249,
  "ctx": "conn5",
  "msg": "Authentication failed",
  "attr": 
    "mechanism": "SCRAM-SHA-256",
    "principalName": "undefined",
    "authenticationDatabase": "admin",
    "client": "172.18.0.5:47568",
    "result": "UserNotFound: Could not find user \"undefined\" for db \"admin\""
  

根据documentation,数据库名称应位于 url 的末尾,如:

url = mongodb://$mongoUser:$mongoPassword@$mongoHostname:$mongoPort/DB-NAME-HERE

由于您可以使用options "user", "pass" and "dbName",我建议从凭据的网址中删除或删除选项userpass

【讨论】:

我已经尝试了所有组合,但我得到了完全相同的错误。看起来它根本没有收到凭据。此外,从 URL 中删除它们是不可能的,因为 URL 不存在? 您确定在网址末尾添加了数据库名称吗?还是同样的错误?我有一个代码可以与 url 中的凭据一起使用,而选项中没有凭据。它与您的架构相同,连接到 mongo 容器。 嘿@bidetaggle,感谢您的帮助。您的答案是正确的,但当时它不起作用,因为我忘记像小丑一样重建我的 docker 映像。所以我所做的代码更改没有反映在图像中。 哈哈,这个不错,很高兴你解决了你的问题。谢谢你告诉我!

以上是关于NestJs / Mongoose 在 Docker 撰写时无法建立 MongoDB 数据库连接的主要内容,如果未能解决你的问题,请参考以下文章

NestJS 和 Mongoose 使用 Mongoose-Sequence

如何用 jest 在服务 (NestJS) 中测试模型 (Mongoose)

Nestjs - Mongoose - 虚拟字段 - 无法在 graphql 操场上查询

如何在 NestJs 和 typescript 中使用 `mongoose-delete` 插件?

NestJS - 如何自我引用 mongoDB 架构 @nestjs/mongoose?

NestJS + Mongoose + GraphQL:“填充”不起作用