Search code examples
c#asp.netdockerrabbitmqmasstransit

RabbitMQ/MassTransit connection refused while running docker


I'm trying to run a .NET 8 web application using MassTransit to connect to RabbitMQ.

During development I just ran my docker-compose file and manually ran the .NET application and this works just fine, all services inside my docker-compose start up correctly and pass their health checks. I was also able to use them in the local running application.

However, the web application inside of the docker-compose is not working an gives the following error during startup:

Connection Failed: rabbitmq://messaging:8085/ <s:MassTransit>
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable
  ---> System.AggregateException: One or more errors occurred. (Connection failed)
  ---> RabbitMQ.Client.Exceptions.ConnectFailureException: Connection failed
  ---> System.Net.Sockets.SocketException (111): Connection refused
    at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
    at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
    at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)

Below are the relevant parts of the docker-compose and configuration.

  messaging:
    image: rabbitmq:management
    container_name: messaging
    hostname: messaging
    restart: always
    volumes:
      - ./.container-data/queue/data:/var/lib/rabbitmq
      - ./.container-data/queue/logs:/var/log/rabbitmq
    ports:
      - 8085:5672
      - 8083:15672
    environment:
      RABBITMQ_DEFAULT_USER: quotable
      RABBITMQ_DEFAULT_PASS: quotable
    networks:
      - quotable-network
    healthcheck:
          test: rabbitmq-diagnostics -q ping
          interval: 5s
          timeout: 15s
          retries: 3
    internal static void AddAndConfigureMassTransit(this WebApplicationBuilder builder)
    {
        ArgumentNullException.ThrowIfNull(builder);

        var config = builder.GetOrAddMassTransitConfig(ServiceCollectionOptions.Return);

        builder.Services.AddMassTransit(massTransitConfig =>
        {
            massTransitConfig.SetKebabCaseEndpointNameFormatter();

            massTransitConfig.AddAndConfigureConsumers();
            massTransitConfig.AddAndConfigureSagas();

            massTransitConfig.UsingRabbitMq((context, rabbitMqConfig) =>
            {
                rabbitMqConfig.Host(new Uri(config.Host), host =>
                {
                    host.Username(config.UserName);
                    host.Password(config.Password);
                });

                rabbitMqConfig.UseInMemoryOutbox(context);

                rabbitMqConfig.ConfigureEndpoints(context);
            });
        });
    }

The config is a custom record:

public sealed record MassTransitConfig
{
    required public string Address { get; init; }
    required public int Port { get; init; }
    required public string UserName { get; init; }
    required public string Password { get; init; }
    public string Host => $"amqp://{Address}:{Port}";
    public string ConnectionString => $"amqp://{UserName}:{Password}@{Address}:{Port}";
}

At first I assumed I had an issue with the host, still directing to localhost:8085 like I do with the local configuration, but no, the host correctly points towards messaging:8085.

My services are up and running correctly, because when I run the web application locally my appsettings use the exact same values (except for switching to localhost instead of the container name).

I'm assuming I'm missing a piece of configuration required when running the application in docker but after looking at it for a day I have been unable to figure it out.


Solution

  • I found the issue.

    I misinterpreted the docs and assumed that if you changed the ports in de docker-compose, you changed the ports on the container. This turns out to not be the case. So while my host forwarded its 8085 port to RabbitMQ's 5672, the container itself still had 5672 as its port.

    Changing the port mapping to 5672:5672 fixed the issue.