skip to Main Content

When i try to run "docker-compose up". It is working. But when i try to run "docker run denexbackend_denex-service". I am getting mongo connection timeout error.

Denex.Backend is open source project.

appsettings.json

  "MongoDbSettings": {
    "ConnectionString": "mongodb://mongodb-service:27017",
    "Database": "DenexDB"
  },

docker-compose.yml

version: '3.8'
services:
  denex-service:
    container_name: denex
    image: mevlutgur/denex.backend:latest
    build: .
    ports:
      - 3003:80
  mongodb-service:
    image: mongo
    ports:
      - 27018:27017
    volumes:
      - denex-data:/data/db
volumes:
  denex-data:

docker-compose.yml (After trying some solutions)

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

dockerfile

FROM mcr.microsoft.com/dotnet/sdk:6.0-jammy AS build
WORKDIR /app

# copy csproj and restore as distinct layers
COPY *.sln .
COPY src/WebApi/Denex.WebApi/Denex.WebApi.csproj ./src/WebApi/Denex.WebApi/
COPY src/Core/Denex.Domain/Denex.Domain.csproj ./src/Core/Denex.Domain/
COPY src/Core/Denex.Application/Denex.Application.csproj ./src/Core/Denex.Application/
COPY src/Infrastructure/Denex.Persistance/Denex.Persistance.csproj ./src/Infrastructure/Denex.Persistance/
COPY tests/WebApi.UnitTest/WebApi.UnitTest.csproj ./tests/WebApi.UnitTest/

RUN dotnet restore

# copy everything else and build app
COPY src/WebApi/Denex.WebApi/. ./src/WebApi/Denex.WebApi/
COPY src/Core/Denex.Domain/. ./src/Core/Denex.Domain/
COPY src/Core/Denex.Application/. ./src/Core/Denex.Application/
COPY src/Infrastructure/Denex.Persistance/. ./src/Infrastructure/Denex.Persistance/
COPY tests/WebApi.UnitTest/. ./tests/WebApi.UnitTest/

WORKDIR /app/src/WebApi/Denex.WebApi
RUN dotnet publish -c Release -o out

WORKDIR /app/tests/WebApi.UnitTest
RUN dotnet test --verbosity quiet

# build runtime image

FROM mcr.microsoft.com/dotnet/aspnet:6.0-jammy AS runtime
WORKDIR /app

COPY --from=build /app/src/WebApi/Denex.WebApi/out ./
EXPOSE 80
ENTRYPOINT ["dotnet", "Denex.WebApi.dll"]

Error message

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

2

Answers


  1. Docker compose is kind of an abstraction layer on top of docker containers.

    So with compose you have services denex-service and mongodb-service, they are treated as hostnames/dns names so in denex-service appsettings.json you can reference it with the service name mongodb-service. Each service is running 1 container by default but compose services can be scaled with the –scale flag on docker compose up ... --scale denex-service=5 so denex-service would be served 5 containers, of course the app must support to be scaled up.

    Also compose projects run in their own docker network by default, created on compose up and removed with compose down, but since you explictly set samplenetwork you compose project will run in this network. If you do docker network ls after compose up you will see samplenetwork

    To run your stuff with bare containers with docker you need to first start the mongo-service container, give the name of it mongo-service (–name flag) so the .NET appsettings.json doesn’t need to be modified. After the container named mongo-service is up and running you can start the .NET app.

    Optionally you can create a separate network for these containers and run them with it (–network flag) instead of the default bridge network, but first you need to create the network.

    docker network create samplebarenetwork

    All in all, docker compose is much more convenient to use than "bare" containers but it is good to know or even mandatory to understand how containers work. Buckle up, because the next stop is kubernetes 😉

    BTW! you should use the Compose V2 that is a subcommand of docker (without dash between docker and compose): docker compose instead of the old compose cli docker-compose: https://www.docker.com/blog/announcing-compose-v2-general-availability/

    Login or Signup to reply.
  2. Are you creating a network when running your non-compose docker commands ?

    You could do :

    docker network create 
      --driver bridge 
      --subnet 182.18.0.1/24 
      --gateway 182.18.0.1 
      samplenetwork
    

    followed by

    docker run 
      -e POSTGRES_PASSWORD=docker 
      --name mongodb-service 
      -p 27018:27017 
      -v 'denex-data:/data/db' 
      --network samplenetwork 
      -d mongo
    

    and then after that you make sure you’ve built a version of your container from your Dockerfile

    docker build -t denex-service -f Dockerfile .
    

    And lastly, you run the version of the container you’ve just built locally :

    docker run 
      --name denex-backend 
      -p 3003:80 
      --network samplenetwork 
      -d denex-service
    

    Good luck, and make sure you double-check my container names and stuff, I could have a typo somewhere but this should work for you.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search