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.
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.