Home > front end >  Cannot authenticate to mongodb
Cannot authenticate to mongodb

Time:06-14

I'm trying to connect to mongodb instance (db container), but I get each time this error:

MongoServerError: Authentication failed.

This is my docker-compose.yml:

version: '3'

services:

  app:
    container_name: ${APP_NAME}_app
    build:
      context: .
    ports:
      - "8088:3001"
    depends_on:
      - db
    environment:
      - DB_HOST=db
      - DB_PORT=${DB_PORT}
      - DB_NAME=${DB_NAME}
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}

  db:
    container_name: ${APP_NAME}_db
    image: mongo
    volumes:
      - ./data:/data/db
    ports:
      - "${DB_PORT}:${DB_PORT}"
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${DB_USER}
      - MONGO_INITDB_ROOT_PASSWORD=${DB_PASSWORD}
      - MONGO_INITDB_DATABASE=${DB_NAME}

These are the variables within .env:

DB_PORT=27017
DB_NAME=mydb
DB_USER=root
DB_PASSWORD=mypwd

This is the connection class:

import * as Mongoose from 'mongoose'
import { UserModel } from './users/users.model'
import { ChatModel } from './chats/chats.model'
import { MessageModel } from './messages/messages.model'

const {
    DB_HOST,
    DB_PORT,
    DB_NAME,
    DB_USER,
    DB_PASSWORD
} = process.env

if (!DB_HOST) throw new TypeError('DB_HOST missing!')
if (!DB_PORT) throw new TypeError('DB_PORT missing!')
if (!DB_NAME) throw new TypeError('DB_NAME missing!')
if (!DB_USER) throw new TypeError('DB_USER missing!')
if (!DB_PASSWORD) throw new TypeError('DB_PASSWORD missing!')

let database: Mongoose.Connection

export const connect = (callback: Function) => {
    
    const uri = `mongodb://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?authSource=admin`

    if (database) {
        return
    }

    Mongoose.connect(uri)

    database = Mongoose.connection

    database.once('open', async () => {
        console.log('Connected to database')

        callback()
    })

    database.on('error', () => {
        console.log('Error connecting to database')
    })

    return {
        UserModel,
        ChatModel,
        MessageModel
    }
}

export const disconnect = () => {

    if (!database) {
        return
    }

    Mongoose.disconnect()
}

This is the list of the running containers:

enter image description here

The app container doesn't run 'cause there is the connection error, but the mongodb container is actually running.

What I did wrong?

CodePudding user response:

I created the following docker-compose.yaml to try to reproduce your problem:

version: "3"

services:
  db:
    container_name: ${APP_NAME}_db
    image: mongo
    ports:
      - "${DB_PORT}:${DB_PORT}"
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${DB_USER}
      - MONGO_INITDB_ROOT_PASSWORD=${DB_PASSWORD}
      - MONGO_INITDB_DATABASE=${DB_NAME}

  client:
    container_name: ${APP_NAME}_client
    image: mongo
    command: sleep inf
    environment:
      - DB_HOST=db
      - DB_PORT=${DB_PORT}
      - DB_NAME=${DB_NAME}
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}

I'm using the .env file you show in your question, with the addition of the APP_NAME variable:

DB_PORT=27017
DB_NAME=mydb
DB_USER=root
DB_PASSWORD=mypwd
APP_NAME=example

If I bring up the stack, and then docker exec into the client container and run:

root@4c7dd638c102:/# mongosh mongodb://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?authSource=admin

It seems to work just fine:

Current Mongosh Log ID: 62a79256b9719bd467e22d03
Connecting to:          mongodb://<credentials>@db:27017/mydb?authSource=admin&directConnection=true
Using MongoDB:          5.0.0
Using Mongosh:          1.0.0
...
mydb>

Have you verified (e.g. by printing it out) that the uri variable in your javascript code contains the value you expect?


If I update my reproducer to use a named volume, like this...

version: "3"

services:
  db:
    container_name: ${APP_NAME}_db
    image: mongo
    ports:
      - "${DB_PORT}:${DB_PORT}"
    volumes:
      - "mongo_data:/data/db"
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${DB_USER}
      - MONGO_INITDB_ROOT_PASSWORD=${DB_PASSWORD}
      - MONGO_INITDB_DATABASE=${DB_NAME}

  client:
    container_name: ${APP_NAME}_client
    image: mongo
    command: sleep inf
    environment:
      - DB_HOST=db
      - DB_PORT=${DB_PORT}
      - DB_NAME=${DB_NAME}
      - DB_USER=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}

volumes:
  mongo_data:

...everything continues to work just fine.

  • Related