Проблемы аутентификации MongoDB с Node.js и Mongo-Express в настройке Docker Compose

Я пытался использовать Docker в проекте, который создал некоторое время назад, и у меня возникли проблемы с аутентификацией MongoDB при использовании Docker Compose. Вот мой docker-compose.yml:

services:
  web:
    build: .
    ports:
      - "${PORT}:${PORT}"
    environment:
      - PORT=${PORT}
      - CONNECTION_STRING=${CONNECTION_STRING}
      - ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
    depends_on:
      - mongo
  mongo:
    image: mongo:latest
    ports:
      - "27017:27017"
    volumes:
      - ./data:/data/db
    environment:
      - MONGO_INITDB_ROOT_USERNAME=${MONGO_INITDB_ROOT_USERNAME}
      - MONGO_INITDB_ROOT_PASSWORD=${MONGO_INITDB_ROOT_PASSWORD}

  mongo-express:
    image: mongo-express
    ports:
      - 8081:8081
    environment:
      - ME_CONFIG_MONGODB_SERVER=mongo
      - ME_CONFIG_MONGODB_ADMINUSERNAME=${MONGO_INITDB_ROOT_USERNAME}
      - ME_CONFIG_MONGODB_ADMINPASSWORD=${MONGO_INITDB_ROOT_PASSWORD}

Dockerfile для создания образа веб-приложения:

FROM node:20-alpine3.19

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5001

CMD ["npm", "run", "start"]

Используемый файл .env:

PORT=5001

CONNECTION_STRING=mongodb://admin:adminpassword@mongo:27017/key_ring_backend_3

MONGO_INITDB_ROOT_USERNAME=admin
MONGO_INITDB_ROOT_PASSWORD=adminpassword

Монго работает без проблем, но веб-приложение и mongo-express не могут подключиться к монго.

Веб-приложение выдает следующую ошибку:

2024-06-27 06:34:30 
2024-06-27 06:34:30 > [email protected] start
2024-06-27 06:34:30 > node ./src/server.js
2024-06-27 06:34:30 
2024-06-27 06:34:30 Server running on port 5001
2024-06-27 06:34:43 Error: MongoServerError: Authentication failed.

Mongo-express выдает следующую ошибку

2024-06-27 06:34:40 Welcome to mongo-express 1.0.2
2024-06-27 06:34:40 ------------------------
2024-06-27 06:34:30 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:30 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:31 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:31 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:32 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:32 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:33 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:33 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:34 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:34 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:35 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:35 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:36 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:36 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:37 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:37 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:38 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:38 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:39 /docker-entrypoint.sh: connect: Connection refused
2024-06-27 06:34:39 /docker-entrypoint.sh: line 15: /dev/tcp/mongo/27017: Connection refused
2024-06-27 06:34:43 Could not connect to database using connectionString: mongodb://admin:****@mongo:27017/"
2024-06-27 06:34:43 /app/node_modules/mongodb/lib/cmap/connection.js:227
2024-06-27 06:34:43                     callback(new error_1.MongoServerError(document));
2024-06-27 06:34:43                              ^
2024-06-27 06:34:43 
2024-06-27 06:34:43 MongoServerError: Authentication failed.
2024-06-27 06:34:43     at Connection.onMessage (/app/node_modules/mongodb/lib/cmap/connection.js:227:30)
2024-06-27 06:34:43     at MessageStream.<anonymous> (/app/node_modules/mongodb/lib/cmap/connection.js:60:60)
2024-06-27 06:34:43     at MessageStream.emit (node:events:517:28)
2024-06-27 06:34:43     at processIncomingData (/app/node_modules/mongodb/lib/cmap/message_stream.js:125:16)
2024-06-27 06:34:43     at MessageStream._write (/app/node_modules/mongodb/lib/cmap/message_stream.js:33:9)
2024-06-27 06:34:43     at writeOrBuffer (node:internal/streams/writable:392:12)
2024-06-27 06:34:43     at _write (node:internal/streams/writable:333:10)
2024-06-27 06:34:43     at Writable.write (node:internal/streams/writable:337:10)
2024-06-27 06:34:43     at Socket.ondata (node:internal/streams/readable:809:22)
2024-06-27 06:34:43     at Socket.emit (node:events:517:28) {
2024-06-27 06:34:43   ok: 0,
2024-06-27 06:34:43   code: 18,
2024-06-27 06:34:43   codeName: 'AuthenticationFailed',
2024-06-27 06:34:43   connectionGeneration: 7,
2024-06-27 06:34:43   [Symbol(errorLabels)]: Set(2) { 'HandshakeError', 'ResetPool' }
2024-06-27 06:34:43 }
2024-06-27 06:34:43 
2024-06-27 06:34:43 Node.js v18.20.3
2024-06-27 06:34:40 
2024-06-27 06:34:40

Все работало нормально, когда я не передал данные пользователя и пароля, как показано ниже:

services:
  web:
    build: .
    ports:
      - "${PORT}:${PORT}"
    environment:
      - PORT=${PORT}
      - CONNECTION_STRING=${CONNECTION_STRING}
      - ACCESS_TOKEN_SECRET=${ACCESS_TOKEN_SECRET}
    depends_on:
      - mongo
  mongo:
    image: mongo:latest
    ports:
      - "27017:27017"
    volumes:
      - ./data:/data/db

  mongo-express:
    image: mongo-express
    ports:
      - 8081:8081

.env также был таким:

CONNECTION_STRING=mongodb://mongo:27017/key_ring_backend_3

У меня нет никаких проблем при такой работе во время разработки. Но можно ли создать сервер mongo без установки пользователя root и пароля во время производства? Или мне не следует создавать таким образом сервер mongo с помощью Docker, а вместо этого использовать что-то вроде онлайн-сервиса mongodb.

🤔 А знаете ли вы, что...
Node.js активно развивается и обновляется, чтобы соответствовать современным стандартам и требованиям.


80
2

Ответы:

Попробуйте эту строку подключения:

mongodb://admin:adminpassword@mongo:27017/key_ring_backend_3?authSource=admin

Я предполагаю, что пользователь создан в базе данных admin. Без authSource драйвер пытается пройти аутентификацию в базе данных key_ring_backend_3, но это не та база данных, в которой создан пользователь.


Решено

Итак, я нашел проблему. Для соединения mongo я добавил громкость как

volumes:
  - ./data:/data/db

При использовании docker-compose и создании контейнеров mongo инициализирует своего администратора, используя значения, предоставленные при первом запуске команды docker-compose up.

В моем случае я изначально запустил файл docker-compose.yml без установки каких-либо MONGO_INITDB_ROOT_USERNAME и MONGO_INITDB_ROOT_PASSWORD. Это привело к тому, что база данных администратора оказалась пустой без пользователей. Это означало, что я даже не смогу запускать такие команды, как db.getUsers(), даже в mongosh.

Теперь, даже если я добавлю MONGO_INITDB_ROOT_USERNAME и MONGO_INITDB_ROOT_PASSWORD в docker-compose.yml и запущу его, он не будет добавлен в базу данных администратора, поскольку установленный мной том принял только те значения, которые использовались при первой его инициализации.

Исправить:

Я удалил каталог data из своей локальной системы, удалил работающие контейнеры и запустил файл docker-compose.yml после установки значений MONGO_INITDB_ROOT_USERNAME и MONGO_INITDB_ROOT_PASSWORD. Это исправило ситуацию.