简体   繁体   English

无法连接本地 mongoDb docker 数据库

[英]Unable to connect ot local mongoDb docker database

I have a problem connecting to a mongoDb from my dotnet core 3.1 application.我在从 dotnet core 3.1 应用程序连接到 mongoDb 时遇到问题。 Both the mongoDb and the API application is running inside container. mongoDb 和 API 应用程序都在容器内运行。 Every container can be reached from the localhost and they are using the default docker network settings.每个容器都可以从本地主机访问,它们使用默认的 docker 网络设置。

My mongoDb docker-compose file我的 mongoDb docker-compose 文件

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"

My application docker-compose file我的应用程序 docker-compose 文件

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"

The reason behind both of them are in a compose file is that there are more services running inside that compose.它们背后的原因都在一个 compose 文件中,因为在该 compose 文件中运行着更多的服务。

My code is following the Microsoft offered mongodb docs .我的代码遵循Microsoft 提供的 mongodb docs And the code is the following:代码如下:

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);
        }
    }

During the insert operation, I get the following exception在插入操作期间,我收到以下异常

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

I have also a visual client installed to see the actual actions and I can confirm that the database/collections specified are existing and accessible by the user.我还安装了一个可视化客户端来查看实际操作,我可以确认指定的数据库/集合是否存在并且用户可以访问。

在此处输入图片说明

Does anybody know what can be the reason for this problem?有谁知道这个问题的原因是什么?

A couple of thoughts..一些想法..

Service Name:服务名称:

mongoDatabase mongo数据库

Shouldn't this be part of your connection string?这不应该是您的连接字符串的一部分吗?

MONGODB_DATABASE MONGODB_DATABASE

The dockerfile for mongo database should have some kind of db init script that creates a database NewsGroup mongo 数据库的 dockerfile 应该有某种创建数据库NewsGroup的 db init 脚本

Restart Policy:重启策略:

I guess the two services spin off almost at the same time Web API is easy and probably gets there sooner.我猜这两个服务几乎同时剥离 Web API 很容易,而且可能会更快到达那里。 MongoDB is taking a little longer. MongoDB 需要更长的时间。 the WebAPI has already crashed by then.那时 WebAPI 已经崩溃了。 A dirty trick is to add a restart policy inside docker-compose of writer.api一个肮脏的技巧是在writer.api -compose 中添加重启策略

restart: on-failure

A better way to is to write a script in Dockerfile for writer API that'll make it wait for the mongodbService to come up更好的方法是在 Dockerfile 中为编写器 API 编写脚本,使其等待mongodbService出现

Edits #1:编辑 #1:

Custom Network across different 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 file: .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

The problem here was that I added an extra "" around the environment variable, therefore it was looking for '"NewsGroup"' database which is non existent.这里的问题是我在环境变量周围添加了一个额外的“”,因此它正在寻找不存在的“NewsGroup”数据库​​。 After I had removed the extra "" is is working as expected.在我删除了额外的“”之后,它按预期工作。

So the final docker environment variable is所以最终的docker环境变量是

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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM