3

I am currently stuck with this problem for about a week and really can't find an appropriate solution. The problem is that when I try to connect to dockerized RabbitMQ it gives me the same error every time:

wordofthedayapp-wordofthedayapp-1  | [40m[1m[33mwarn[39m[22m[49m: MassTransit[0]
wordofthedayapp-wordofthedayapp-1  |       Connection Failed: rabbitmq://localhost/
wordofthedayapp-wordofthedayapp-1  |       RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were
 reachable
wordofthedayapp-wordofthedayapp-1  |        ---> System.AggregateException: One or more errors occurred. (Connection failed)
wordofthedayapp-wordofthedayapp-1  |        ---> RabbitMQ.Client.Exceptions.ConnectFailureException: Connection failed
wordofthedayapp-wordofthedayapp-1  |        ---> System.TimeoutException: The operation has timed out.
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.TaskExtensions.TimeoutAfter(Task task, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectOrFail(ITcpClient socket, AmqpTcpEndpo
int endpoint, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          --- End of inner exception stack trace ---
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectOrFail(ITcpClient socket, AmqpTcpEndpo
int endpoint, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectUsingAddressFamily(AmqpTcpEndpoint end
point, Func`2 socketFactory, TimeSpan timeout, AddressFamily family)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectUsingIPv4(AmqpTcpEndpoint endpoint, Fu
nc`2 socketFactory, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler..ctor(AmqpTcpEndpoint endpoint, Func`2 socket
Factory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Framing.Impl.IProtocolExtensions.CreateFrameHandler(IProtocol protoco
l, AmqpTcpEndpoint endpoint, Func`2 socketFactory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateFrameHandler(AmqpTcpEndpoint endpoint)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, F
unc`2 selector)
wordofthedayapp-wordofthedayapp-1  |          --- End of inner exception stack trace ---
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, F
unc`2 selector)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver
, String clientProvidedName)
wordofthedayapp-wordofthedayapp-1  |          --- End of inner exception stack trace ---
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver
, String clientProvidedName)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateConnection(IList`1 hostnames, String clientPr
ovidedName)
wordofthedayapp-wordofthedayapp-1  |          at MassTransit.RabbitMqTransport.Integration.ConnectionContextFactory.CreateConnection(I
Supervisor supervisor)

Here you can find my docker-compose.yml:

version: '3.9'
services:
  rabbitmq:
    image: rabbitmq:3.9-management
    hostname: rabbitmq
    volumes:
      - "~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/"
      - "~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq"
    ports:
      - 5672:5672
      - 15672:15672
    expose:
     - 5672
     - 15672
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
    healthcheck:
        test: [ "CMD", "rabbitmqctl", "status", "-f", "http://localhost:15672"]
        interval: 5s
        timeout: 20s
        retries: 5
    networks:
      - app

  ms-sql-server:
    container_name: ms-sql-server
    image: mcr.microsoft.com/mssql/server:2019-latest
    user: root
    volumes:
      - "appdb:/var/opt/mssql/data"
    environment:
      ACCEPT_EULA: "Y"
      SA_PASSWORD: "Password123!"
      MSSQL_PID: Express
    ports:
      - 1433:1433
    healthcheck:
        test: ["CMD" ,"ping", "-h", "localhost"]
        timeout: 20s
        retries: 10
    networks:
      - app

  wordofthedayapp:
    build:
      dockerfile: WordOfTheDay.Api/Dockerfile
    image: wordofthedayapp
    environment:
      DbServer: "ms-sql-server"
      DbPort: "1433"
      DbUser: "sa"
      Password: "Password123!"
      Database: "appdb"
    ports:
      - 5001:80
    restart: on-failure
    depends_on:
      - rabbitmq
    networks:
      - app

volumes:
  appdb:

networks:
  app:

My appsettings string:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "WordContext": "Server=ms-sql-server;Database=master;User=sa;Password=Password123!;MultipleActiveResultSets=true;Integrated Security=false;TrustServerCertificate=true",
    "RabbitMQHost": "amqp://elias:123456@localhost:5672"
  }
}

This is how it works in the app using MassTransit:

public static void AddConfiguredMassTransit(this IServiceCollection services, string host)
        {
            services.AddMassTransit(Configuration =>
            {
                Configuration.UsingRabbitMq((context, config) =>
                {
                    config.Host(host);
                });
            });

            services.AddMassTransitHostedService();
        }
services.AddConfiguredMassTransit(Configuration.GetConnectionString("RabbitMQHost"));

I hope at least anyone knows what is wrong with this code because I really tired trying to fix it and browsing internet for solution. Thank you in advance!

P.S. Important information! Everything works perfect when I test it locally without a docker, but when I try to dockerize the app this happens.

  • In the same way you use the Compose service name `ms-sql-server` as a host name to connect to the database, you need to use the Compose service name `rabbitmq` as a host name to connect to the message queue in the `RabbitMQHost` setting. `localhost` in Docker usually means "the current container". – David Maze Feb 07 '22 at 17:19

1 Answers1

4

If you are testing locally, the host is likely localhost since Docker is exposing the port to the local machine. When running in a container, however, the virtual network should have a hostname of rabbitmq, which would need to be used instead of localhost when running inside a container on the same network.

Since the log shows:

Connection Failed: rabbitmq://localhost/

I'm guessing you aren't updating the host name when running inside a container.

You can determine if your application is running in a container easily:

bool IsRunningInContainer => bool.TryParse(Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER"), out var inDocker) && inDocker;

Then, in your configuration:

var host = IsRunningInContainer ? "rabbitmq" : "localhost";

Chris Patterson
  • 28,659
  • 3
  • 47
  • 59