Weโll run RabbitMQ in Docker on an AWS EC2 instance, and use your Windows laptop for both the producer and consumer.
Iโll walk you through:
- Create & configure EC2
- Install Docker & run RabbitMQ container
- Securely expose RabbitMQ over IP
- Write .NET Producer (Windows)
- Write .NET Consumer (Windows)
- Test end-to-end
1. Provision AWS EC2 for RabbitMQ
1.1 Launch EC2 instance
In AWS Console:
- Go to EC2 โ Instances โ Launch instance.
- Name:
rabbitmq-ec2. - AMI:
- Ubuntu Server 22.04 LTS (or Amazon Linux if you prefer).
- Instance type:
t3.smallort3.microis OK for demo. - Key Pair: select or create one (for SSH).
- Network:
- VPC: default (or your custom VPC).
- Subnet: any public subnet.
- Auto-assign Public IP: Enable โ (important).
1.2 Security group ports
Create or configure a security group, e.g., rabbitmq-sg, with:
- SSH: TCP 22, Source = your IP only (e.g.,
x.x.x.x/32). - RabbitMQ AMQP: TCP 5672, Source = your IP (for .NET code) or office IP range.
- RabbitMQ Management UI: TCP 15672, Source = your IP (for browser access).
Donโt leave 0.0.0.0/0 open in production. For demo itโs โokay-ishโ, but better to restrict.
Launch the instance.
2. Install Docker & run RabbitMQ on EC2
2.1 SSH into the EC2 instance
From your Windows laptop:
ssh -i "your-key.pem" ubuntu@EC2_PUBLIC_IP
Code language: CSS (css)
(Replace your-key.pem path and EC2_PUBLIC_IP with the instanceโs public IP.)
2.2 Install Docker (Ubuntu example)
# Update packages
sudo apt-get update
# Install Docker
sudo apt-get install -y docker.io
# Enable & start Docker
sudo systemctl enable docker
sudo systemctl start docker
# Verify
docker --version
Code language: PHP (php)
2.3 Run RabbitMQ Docker container (with remote access)
Important: the default guest user cannot log in remotely (only from localhost), so weโll create a new user.
Run RabbitMQ with management:
sudo docker run -d \
--hostname my-rabbit \
--name rabbitmq-demo \
-p 5672:5672 \
-p 15672:15672 \
rabbitmq:3-management
Code language: CSS (css)
Wait a few seconds, then:
sudo docker ps
You should see rabbitmq:3-management running.
2.4 Create a dedicated user for remote access
Connect into the container:
sudo docker exec -it rabbitmq-demo bash
Inside the container:
# Add a user - choose your own username & password
rabbitmqctl add_user myuser mypassword
# Give full permissions on the default vhost "/"
rabbitmqctl set_permissions -p / myuser ".*" ".*" ".*"
# (Optional) Give administrator tag for UI access
rabbitmqctl set_user_tags myuser administrator
exit
Code language: PHP (php)
Now youโll use myuser / mypassword from Windows.
3. Verify RabbitMQ Management UI from your laptop
On your Windows laptop, open browser:
http://EC2_PUBLIC_IP:15672
Code language: JavaScript (javascript)
Log in with:
- Username:
myuser - Password:
mypassword
You should see the RabbitMQ dashboard ๐
4. Prepare .NET projects on Windows laptop
Weโll create two console apps on your laptop:
RabbitMqProducerโ sends messages to EC2 RabbitMQRabbitMqConsumerโ receives & processes them
4.1 Create solution & projects
In PowerShell / CMD:
mkdir RabbitMqEc2Demo
cd RabbitMqEc2Demo
dotnet new sln -n RabbitMqEc2Demo
dotnet new console -n RabbitMqProducer
dotnet new console -n RabbitMqConsumer
dotnet sln add RabbitMqProducer/RabbitMqProducer.csproj
dotnet sln add RabbitMqConsumer/RabbitMqConsumer.csproj
Code language: JavaScript (javascript)
4.2 Install RabbitMQ client in both apps
cd RabbitMqProducer
dotnet add package RabbitMQ.Client
cd ..
cd RabbitMqConsumer
dotnet add package RabbitMQ.Client
cd ..
Code language: CSS (css)
5. Producer code (from Windows โ EC2 RabbitMQ)
Edit RabbitMqProducer/Program.cs and replace with:
using System.Text;
using RabbitMQ.Client;
Console.WriteLine("RabbitMQ Producer starting...");
// Replace with your EC2 public IP or DNS
var rabbitMqHost = "EC2_PUBLIC_IP_OR_DNS"; // e.g. "3.110.45.123"
var queueName = "demo_queue";
var factory = new ConnectionFactory
{
HostName = rabbitMqHost,
Port = 5672,
UserName = "myuser", // user created on EC2 RabbitMQ
Password = "mypassword", // password you set
VirtualHost = "/" // default vhost
};
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
// Declare queue - safe to call many times
channel.QueueDeclare(
queue: queueName,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
Console.WriteLine($"Connected to RabbitMQ at {rabbitMqHost}. Queue: {queueName}");
for (int i = 1; i <= 10; i++)
{
var message = $"Hello from Windows Producer! Message #{i}";
var body = Encoding.UTF8.GetBytes(message);
var properties = channel.CreateBasicProperties();
properties.Persistent = true; // store on disk
channel.BasicPublish(
exchange: "",
routingKey: queueName,
basicProperties: properties,
body: body);
Console.WriteLine($"[x] Sent: {message}");
}
Console.WriteLine("All messages sent. Press any key to exit.");
Console.ReadKey();
Code language: JavaScript (javascript)
6. Consumer code (from Windows โ EC2 RabbitMQ)
Edit RabbitMqConsumer/Program.cs and replace with:
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
Console.WriteLine("RabbitMQ Consumer starting...");
// Same EC2 host & credentials
var rabbitMqHost = "EC2_PUBLIC_IP_OR_DNS"; // e.g. "3.110.45.123"
var queueName = "demo_queue";
var factory = new ConnectionFactory
{
HostName = rabbitMqHost,
Port = 5672,
UserName = "myuser",
Password = "mypassword",
VirtualHost = "/",
DispatchConsumersAsync = true
};
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(
queue: queueName,
durable: true,
exclusive: false,
autoDelete: false,
arguments: null);
// Optional QoS to process one message at a time
channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false);
Console.WriteLine($"Connected to RabbitMQ at {rabbitMqHost}. Waiting for messages on queue: {queueName}");
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.Received += async (model, ea) =>
{
var body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
Console.WriteLine($"[x] Received: {message}");
// Simulate some processing work
await Task.Delay(500);
// Acknowledge the message
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(
queue: queueName,
autoAck: false,
consumer: consumer);
Console.WriteLine("Press [enter] to exit.");
Console.ReadLine();
Code language: JavaScript (javascript)
7. Run the full flow
7.1 Start the consumer (Windows)
Open terminal on your laptop:
cd RabbitMqEc2Demo/RabbitMqConsumer
dotnet run
You should see:
RabbitMQ Consumer starting...
Connected to RabbitMQ at EC2_PUBLIC_IP_OR_DNS. Waiting for messages on queue: demo_queue
Press [enter] to exit.
Code language: CSS (css)
(Queue might be empty initially.)
7.2 Run the producer (Windows)
Open another terminal:
cd RabbitMqEc2Demo/RabbitMqProducer
dotnet run
You should see:
RabbitMQ Producer starting...
Connected to RabbitMQ at EC2_PUBLIC_IP_OR_DNS. Queue: demo_queue
[x] Sent: Hello from Windows Producer! Message #1
...
[x] Sent: Hello from Windows Producer! Message #10
All messages sent. Press any key to exit.
Code language: CSS (css)
Now check the consumer terminal; you should see each message being received & processed:
[x] Received: Hello from Windows Producer! Message #1
[x] Received: Hello from Windows Producer! Message #2
...
Code language: CSS (css)
7.3 Inspect via RabbitMQ Management UI
In browser:
http://EC2_PUBLIC_IP:15672
Code language: JavaScript (javascript)
Log in with myuser / mypassword.
- Go to Queues โ click
demo_queue - You can see:
- Ready / unacked messages counts
- Consumers count
- Message rates
Try experiments:
- Stop consumer, run producer โ messages accumulate in queue.
- Start consumer again โ it drains messages from queue.
8. Hardening / Production Thoughts (for your training)
You can mention this in your tutorial:
- Use non-default credentials, strong passwords.
- Restrict Security Group to your office VPN / corporate IPs.
- Consider TLS for RabbitMQ traffic (amqps).
- Use separate vhosts for environments (dev / stage / prod).
- Use Docker volumes or EBS volumes for persistent data.
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services โ all in one place.
Explore Hospitals
This blog offers a practical and easy-to-follow introduction to using RabbitMQ with .NET, supported by clear demo and lab-style examples. The step-by-step approach helps developers understand message publishing, consumption, and queue handling in a real application context. By focusing on hands-on implementation rather than just theory, the article makes it easier to grasp asynchronous communication and decoupled system design. Overall, it is a useful resource for .NET developers who want to build reliable messaging-based applications and gain confidence working with RabbitMQ in real-world scenarios.
This is a great tutorial โ the detailed demo and lab example with RabbitMQ and .NET plainly show how message-based architecture can simplify asynchronous communication and improve scalability. Walking through queue setup, producer/consumer code, and handling message acknowledgments makes it much easier to grasp for developers new to messaging systems. I appreciate how the article balances theory with hands-on code โ that kind of practical approach helps teams adopt robust, event-driven patterns with confidence. Well done โ this is a valuable resource for anyone looking to implement reliable messaging in .NET applications.