[SOLVED] Can't connect RabbitMQ to my app from docker

Issue

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:[email protected]: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.

Solution

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";

Answered By – Chris Patterson

Answer Checked By – Senaida (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *