Не удается подключиться к MongoDB в контейнере docker через имя хоста - PullRequest
0 голосов
/ 09 мая 2020

Я работаю над небольшим личным проектом и недавно перешел с PostgreSQL на MongoDB. Mon go работает в контейнере docker, и при локальном запуске моего API все работает нормально. Однако, когда я пытаюсь запустить свой API в docker, единственный способ заставить его успешно подключиться к Mon go - это использовать IP-адрес моей локальной сети для строки подключения. Когда я пытаюсь подключиться через имя хоста (host.docker.internal или mon go имя контейнера mongo), он не может подключиться. Я подтвердил, что и curl host.docker.internal:27017, и curl mongo:27017 прошли успешно.

Другими словами, строка подключения отформатирована как mongodb://user:pwd@host/database. При локальном запуске это работает с host = "localhost", и это работает с docker с host = "my.local.ip", но не с host = "host.docker.internal" или host = "mongo".

Подключение:

var mongoClient = new MongoClient(
                $"mongodb://{dbCreds.Username}:{dbCreds.Password}@{dbCreds.Host}/{dbCreds.Database}");

docker_compose.yaml:

version: '3.7'
services:
    homenotify.api:
        build: ./HomeNotify.API
        ports:
            - '5000:80'
        networks:
            - api
            - db
        environment:
            - GOOGLE_CREDENTIAL=service_account_key.json
            - DB_CREDENTIALS=db_credentials_docker.json
networks:
    api:
        name: api
        driver: bridge
    db:
        name: db
        external: true

Трассировка стека:

Unhandled exception. System.TimeoutException: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "Automatic", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/mongo:27017" }", EndPoint: "Unspecified/mongo:27017", ReasonChanged: "Heartbeat", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.

---> System.PlatformNotSupportedException: Sockets on this platform are invalid for use after a failed connection attempt.

at System.Net.Sockets.Socket.ThrowMultiConnectNotSupported()

at System.Net.Sockets.Socket.BeginConnect(String host, Int32 port, AsyncCallback requestCallback, Object state)

at MongoDB.Driver.Core.Connections.TcpStreamFactory.ConnectAsync(Socket socket, EndPoint endPoint, CancellationToken cancellationToken)

at MongoDB.Driver.Core.Connections.TcpStreamFactory.CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken)

at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)

1 Ответ

1 голос
/ 10 мая 2020

По-видимому, do tnet имеет проблему с сокетами, не поддерживающими имена хостов на платформах, отличных от Windows. Вот почему он работает локально, но не работает в docker: он включен Windows при локальном запуске и Linux при работе в docker. Предположительно, это было фиксированные годы a go, но проблема именно в этом.

Вручную разрешив IP-адрес из имени хоста и используя вместо этого IP-адрес для подключения, я решил проблему. Здесь нашел фрагмент кода .

dbCreds.Host = Dns.GetHostAddresses(dbCreds.Host)
                .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString();
...