2 votes

Impossible de se connecter à la base de données docker mongoDb locale

J'ai un problème de connexion à une mongoDb depuis mon application dotnet core 3.1. Le mongoDb et l'application API sont tous deux exécutés dans un conteneur. Chaque conteneur est accessible depuis l'hôte local et utilise les paramètres réseau par défaut de Docker.

Mon fichier docker-compose mongoDb

version: "3.4"

services:
  mongoDatabase:
    restart: always
    image: mongo:latest
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=rootPassword
    volumes:
      - ./mongoDatabase:/data/db
    ports:
      - "27017:27017"

Le fichier docker-compose de mon application

writer.api:
    image: ${DOCKER_REGISTRY-}writerapi
    build:
      context: .
      dockerfile: Services/Writer/Writer.API/Dockerfile
    environment:
        - MONGODB_CONNECTION=mongodb://root:rootPassword@host.docker.internal:27017/NewsGroup
        - MONGODB_DATABASE="NewsGroup"
        - MONGODB_COLLECTION_NAME="News"
    ports:
        - "10020:80"

La raison pour laquelle les deux sont dans un fichier compose est qu'il y a plus de services fonctionnant dans ce compose.

Mon code suit le modèle Microsoft a proposé des documents sur mongodb . Et le code est le suivant :

public class MongoDatabaseService : IMongoDatabaseService
    {
        private IMongoDatabase _context;
        private IMongoCollection<ArticleGroup> _articleGroup;

        public MongoDatabaseService()
        {
            string mongoConnectionString = Environment.GetEnvironmentVariable("MONGODB_CONNECTION");
            if (string.IsNullOrEmpty(mongoConnectionString))
            {
                throw new Exception("MongoConnectionstring is empty");
            }

            string mongoDatabase = Environment.GetEnvironmentVariable("MONGODB_DATABASE");
            if (string.IsNullOrEmpty(mongoDatabase))
            {
                throw new Exception("MongoDatabase name is empty");
            }
            var client = new MongoClient(mongoConnectionString);
            _context = client.GetDatabase(mongoDatabase);

            string collectionName = Environment.GetEnvironmentVariable("MONGODB_COLLECTION_NAME");
            if (string.IsNullOrEmpty(mongoDatabase))
            {
                throw new Exception("MongoDatabase collection is empty");
            }
            _articleGroup = _context.GetCollection<ArticleGroup>(collectionName);
        }

        public void AddArticleGroup(ArticleGroup newGroup)
        {
            _articleGroup.InsertOne(newGroup);
        }
    }

Pendant l'opération d'insertion, j'obtiens l'exception suivante

MongoDB.Driver.MongoAuthenticationException: 'Unable to authenticate using sasl protocol mechanism SCRAM-SHA-1.'
MongoCommandException: Command saslStart failed: Authentication failed..

J'ai également installé un client visuel pour voir les actions réelles et je peux confirmer que les bases de données/collections spécifiées existent et sont accessibles par l'utilisateur.

enter image description here

Quelqu'un sait-il quelle peut être la raison de ce problème ?

1voto

Ziaullah Khan Points 146

Quelques réflexions

Nom du service :

mongoDatabase

Cela ne devrait-il pas faire partie de votre chaîne de connexion ?

MONGODB_DATABASE

Le dockerfile pour la base de données mongo devrait avoir une sorte de db init script qui crée une base de données. NewsGroup

Politique de redémarrage :

Je suppose que les deux services sont créés presque en même temps. L'API Web est facile et arrive probablement plus tôt. MongoDB prend un peu plus de temps. l'API Web a déjà planté à ce moment-là. Une astuce consiste à ajouter une politique de redémarrage à l'intérieur de docker-compose, à savoir writer.api

restart: on-failure

Une meilleure façon de procéder est d'écrire un script dans le Dockerfile pour l'API de l'écrivain qui le fera attendre le mongodbService pour monter

Edits #1 :

Réseau personnalisé à travers différents services :

...
  movieapi:
    build: 
        context: .
        dockerfile: Dockerfile.api
    restart: always
    ports:
      - "9000:80"
    depends_on:
      - moviedb
    networks:
      public_net:
        ipv4_address: ${MVCMOVIE_API_1_IP}
...
networks:
  public_net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: ${NETWORK_SUBNET}
...

.env :

COMPOSE_PROJECT_NAME=app_name

MVCMOVIE_EXPOSED_PORT=80

MVCMOVIE_API_1_IP=192.168.0.10
MVCMOVIE_WEB_1_IP=192.168.0.20
MVCMOVIE_WEB_2_IP=192.168.0.21
MVCMOVIE_DB_1_IP=192.168.0.30

HA_PROXY_IP=192.168.0.99

NETWORK_SUBNET=192.168.0.0/24

0voto

Sándor Jankovics Points 618

Le problème est que j'ai ajouté un "" supplémentaire autour de la variable d'environnement, ce qui fait que la base de données '"NewsGroup" est recherchée, alors qu'elle n'existe pas. Après avoir supprimé le "" supplémentaire, le système fonctionne comme prévu.

Donc la variable d'environnement finale de docker est

writer.api:
    image: ${DOCKER_REGISTRY-}writerapi
    build:
      context: .
      dockerfile: Services/Writer/Writer.API/Dockerfile
    environment:
        - MONGODB_CONNECTION=mongodb://root:rootPassword@host.docker.internal:27017/NewsGroup
        - MONGODB_DATABASE=NewsGroup
        - MONGODB_COLLECTION_NAME=News
    ports:
        - "10020:80"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X