[英]Can't connect to MongoDB in docker container via hostname
我正在从事一个小型个人项目,最近从 PostgreSQL 切换到 MongoDB。 Mongo 在 docker 容器中运行,在本地运行我的 API 时,一切正常。 但是,当我尝试在 docker 中运行我的 API 时,我可以让它成功连接到 Mongo 的唯一方法是使用我的本地网络 IP 作为连接字符串。 当我尝试通过主机名( host.docker.internal
或 mongo 容器名称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)
显然,dotnet 存在 sockets 不支持非 Windows 平台上的主机名的问题。 这就是为什么它在本地工作但在 docker 中不起作用的原因:在本地运行时它在 Windows 上,在 Linux 中运行时在 Z0306AFD6.DADF6.DA 据说这在几年前就已经解决了,但这就是问题所在。
从主机名手动解析 IP 地址,并改用 IP 连接,解决了我的问题。 在这里找到了代码片段。
dbCreds.Host = Dns.GetHostAddresses(dbCreds.Host)
.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.