Create your own
Lesson illustration

Running RabbitMQ Locally with Docker

Hello! Welcome to the first lesson of our third module, "Asynchronous Messaging with Message Brokers."

Introduction

In the previous module, we established a strong theoretical foundation for distributed communication. We explored synchronous vs. asynchronous patterns, the importance of idempotency, and the critical trade-offs between at-least-once, at-most-once, and exactly-once delivery semantics.

Now, we shift from theory to practice. The goal of this module is to get hands-on with a real message broker. To do that, we first need to set one up. This lesson will guide you through installing and running RabbitMQ, a widely-used message broker, in a local development environment.

Learning Outcome:

Install and run a RabbitMQ instance locally using Docker.

We will use Docker for this task. Your experience in tech environments means you're likely familiar with containerization, and using Docker provides a clean, isolated, and reproducible setup, which is standard practice for modern development. This will give us a stable platform for the coding exercises in the lessons to come.


1. Why RabbitMQ and Docker?

RabbitMQ is a mature and powerful open-source message broker that implements the Advanced Message Queuing Protocol (AMQP). It acts as the intermediary in asynchronous systems, receiving messages from producers and routing them to consumers. It's a perfect tool for building the patterns we've discussed, such as pub/sub and competing consumers.

We'll be using the rabbitmq:management Docker image, which conveniently bundles the RabbitMQ server with a web-based management UI. This UI is invaluable for visualizing queues, exchanges, and message flow, making it much easier to understand what's happening inside the broker.


2. Method 1: The Direct Approach with docker run

The most direct way to run a Docker container is with the docker run command. This command creates a new container from an image and starts it.

To see this in action and get a clear explanation of the command's components, let's watch a short video.

Running RabbitMQ Locally with Docker

The video 'Running RabbitMQ Locally with Docker' by IAmTimCorey provides an excellent walkthrough of the docker run command for RabbitMQ. It clearly explains the purpose of each flag.

Please watch the segment from 01:34 to 04:28. Focus on how the docker run command is constructed and the meaning of the -d, --name, and -p flags.

As the video demonstrates, the command to start a RabbitMQ container is structured as follows. Note that the video uses 8080 for the management port, but we will stick to the default 15672 for clarity.

docker run \
  -d \
  --hostname my-rabbit \
  --name rabbitmq-instance \
  -p 5672:5672 \
  -p 15672:15672 \
  rabbitmq:3-management

Let's break down this command:

  • docker run: The fundamental command to create and start a container.
  • -d: Runs the container in detached mode, meaning it runs in the background and doesn't lock up your terminal.
  • --hostname my-rabbit: Sets the hostname inside the container. This is the name the RabbitMQ node will identify itself with.
  • --name rabbitmq-instance: Assigns a convenient, human-readable name to the Docker container itself. This makes it easier to manage (e.g., docker stop rabbitmq-instance).
  • -p 15672:15672: This is the port mapping for the management UI. It maps port 15672 on your host machine to port 15672 inside the container.
  • -p 5672:5672: This maps the port for the AMQP protocol, which is how our Python applications will connect to the broker.
  • rabbitmq:3-management: This specifies the image to use from Docker Hub. The 3-management tag ensures we get a version 3 RabbitMQ server that includes the management plugin.

After running this, you could verify the installation by accessing the management UI at http://localhost:15672 and logging in with guest / guest.


3. Method 2: The Declarative Approach with docker-compose

While docker run is great for simple, one-off containers, a more robust and scalable approach is to use docker-compose. This tool uses a YAML file to define a multi-service application. For our purposes, it has several advantages:

  • Declarative: The configuration is stored in a file (docker-compose.yml), which can be version-controlled.
  • Reproducible: Anyone with Docker can spin up the exact same environment with a single command.
  • Manageable: It simplifies starting, stopping, and managing the application's components.

This approach is much closer to how services are managed in professional development and operations.

The following article provides a concise guide to setting up RabbitMQ using docker-compose.

Simplifying RabbitMQ Setup with Docker: A Step-by- ...

The article 'Simplifying RabbitMQ Setup with Docker' explains how to define and run RabbitMQ using a docker-compose.yml file.

Please read from 'Step 2: Writing the Docker Compose File' through to 'Step 4: Verifying Installation'. Focus on the structure of the docker-compose.yml file and the commands used to start and verify the service.

Your Turn: Practical Setup

Now it's time to get your hands dirty. We will use the docker-compose method as it represents a better long-term practice.

  1. Create a Project Directory: Create a new folder on your machine for this module's work (e.g., distributed-systems-course).

  2. Create the docker-compose.yml file: Inside your new directory, create a file named docker-compose.yml and add the following content. This configuration is based on the article you just reviewed.

    version: '3.8'
    
    services:
      rabbitmq:
        image: rabbitmq:3-management
        container_name: rabbitmq
        ports:
          - "5672:5672"    # Port for AMQP client connections
          - "15672:15672"  # Port for the management UI
        volumes:
          - rabbitmq_data:/var/lib/rabbitmq
    
    volumes:
      rabbitmq_data:
    

    A note on volumes: I've added a volumes section. This tells Docker to create a persistent storage volume named rabbitmq_data. This means if you stop and remove the container, your data (like created queues or exchanges) won't be lost. This is useful for development.

  3. Start the Container: Open a terminal, navigate to the directory containing your docker-compose.yml file, and run the following command:

    docker-compose up -d
    

    Docker will now pull the rabbitmq:3-management image (if you don't have it locally) and start the container in detached mode.

  4. Verify the Installation:

    • First, check that the container is running by executing docker ps. You should see a container named rabbitmq in the output.
    • Next, open your web browser and navigate to http://localhost:15672.
    • You should be greeted by the RabbitMQ Management login screen. Log in with the default username guest and password guest.

If you can see the "Overview" dashboard with charts for message rates and a list of nodes, your installation is successful.

To stop the service later, you can run docker-compose down from the same directory. This will stop and remove the container.


Conclusion

Congratulations! You have successfully installed and run a RabbitMQ message broker on your local machine using Docker and docker-compose. This is a foundational step for building and experimenting with asynchronous, message-driven systems.

Key Takeaways:

  • RabbitMQ is a powerful message broker that we can easily run locally using Docker.
  • The rabbitmq:3-management image includes a vital web-based UI for monitoring and administration.
  • docker run is a direct way to start a container, but docker-compose provides a more manageable and declarative approach by defining services in a YAML file.
  • Port mapping (-p) is essential for exposing services running inside a container (like the RabbitMQ broker and its UI) to your host machine.

Preview of the Next Lesson:

With our RabbitMQ broker now running, we are ready to start interacting with it. In the next lesson, we will use a Python client library to connect to our local RabbitMQ instance. You will write code to programmatically declare an exchange and a queue and then bind them together to implement a classic publish/subscribe (pub/sub) pattern.

Can't find a good explanation? Sign up and we'll make it for you

Sign up