Docker-compose运行正常,docker run启动容器时Mongo连接超时
问题解决:Docker单独启动容器无法连接MongoDB(主机名解析失败)
问题现象
执行docker-compose up时Denex.Backend项目可正常运行,但执行docker run denexbackend_denex-service单独启动容器时,出现MongoDB连接超时错误,核心报错为:
System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name or service not known
即无法解析mongodb-service主机名。
原因分析
Docker Compose会自动为项目创建专属网络(无论是默认网络还是自定义的samplenetwork),在这个网络内的容器可以通过服务名称(如mongodb-service)互相访问。但单独使用docker run启动的容器默认加入Docker的公共bridge网络,该网络与Compose创建的项目网络不互通,因此无法解析仅在项目网络内有效的服务主机名。
解决方案
方案1:将容器加入Compose项目网络
先查看Compose创建的网络名称:
docker network ls找到对应项目的网络(例如自定义的
samplenetwork,或默认的<项目目录名>_default)启动容器时指定该网络:
docker run --network samplenetwork denexbackend_denex-service
方案2:修改连接字符串为宿主机IP(测试场景)
- 修改
appsettings.json中的MongoDB连接字符串,将mongodb-service替换为宿主机的IP地址:"MongoDbSettings": { "ConnectionString": "mongodb://<宿主机IP>:27018", "Database": "DenexDB" } - 重新构建镜像:
docker-compose build denex-service - 再用
docker run启动容器即可连接到宿主机映射的MongoDB端口。
方案3:使用docker-compose run启动容器
直接通过Compose命令启动服务容器,它会自动加入项目网络:
docker-compose run denex-service
相关配置参考
appsettings.json
"MongoDbSettings": { "ConnectionString": "mongodb://mongodb-service:27017", "Database": "DenexDB" },
调整后的docker-compose.yml
version: '3.8' services: mongodb-service: image: mongo ports: - 27018:27017 volumes: - denex-data:/data/db networks: - samplenetwork denex-service: container_name: denex-backend build: . ports: - 3003:80 depends_on: - mongodb-service networks: - samplenetwork volumes: denex-data: networks: samplenetwork: driver: bridge
完整错误信息
Unhandled exception. System.TimeoutException: A timeout occurred after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "1", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/mongodb-service:27017" }", EndPoint: "Unspecified/mongodb-service:27017", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 0xFFFDFFFF): Name or service not known at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, ValueStopwatch stopwatch) at System.Net.Dns.GetHostAddresses(String hostNameOrAddress, AddressFamily family) at MongoDB.Driver.Core.Connections.TcpStreamFactory.ResolveEndPoints(EndPoint initial) at MongoDB.Driver.Core.Connections.TcpStreamFactory.CreateStream(EndPoint endPoint, CancellationToken cancellationToken) at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken) --- End of inner exception stack trace --- at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelper(CancellationToken cancellationToken) at MongoDB.Driver.Core.Connections.BinaryConnection.Open(CancellationToken cancellationToken) at MongoDB.Driver.Core.Servers.ServerMonitor.InitializeConnection(CancellationToken cancellationToken) at MongoDB.Driver.Core.Servers.ServerMonitor.Heartbeat(CancellationToken cancellationToken)", LastHeartbeatTimestamp: "2022-11-13T19:16:54.6844686Z", LastUpdateTimestamp: "2022-11-13T19:16:54.6844692Z" }] }. at MongoDB.Driver.Core.Clusters.Cluster.ThrowTimeoutException(IServerSelector selector, ClusterDescription description) at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChangedHelper.HandleCompletedTask(Task completedTask) at MongoDB.Driver.Core.Clusters.Cluster.WaitForDescriptionChanged(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken) at MongoDB.Driver.Core.Clusters.Cluster.SelectServer(IServerSelector selector, CancellationToken cancellationToken) at MongoDB.Driver.MongoClient.AreSessionsSupportedAfterServerSelection(CancellationToken cancellationToken) at MongoDB.Driver.MongoClient.AreSessionsSupported(CancellationToken cancellationToken) at MongoDB.Driver.MongoClient.StartImplicitSession(CancellationToken cancellationToken) at MongoDB.Driver.OperationExecutor.StartImplicitSession(CancellationToken cancellationToken) at MongoDB.Driver.MongoDatabaseImpl.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken) at MongoDB.Driver.MongoDatabaseImpl.ListCollectionNames(ListCollectionNamesOptions options, CancellationToken cancellationToken) at Denex.Persistance.Extensions.MongoImportExtension.AddMongoImport(IConfiguration configuration) in /app/src/Infrastructure/Denex.Persistance/Extensions/MongoImportExtension.cs:line 19 at Program.<Main>$(String[] args) in /app/src/WebApi/Denex.WebApi/Program.cs:line 24
内容的提问来源于stack exchange,提问作者Mevlüt Gür
相关产品推荐
相关产品推荐

