docker network create rabbits

docker run -d --rm --net rabbits --hostname rabbit-1 --name rabbit-1 rabbitmq:3.8

RabbitMQ use <identifier>@<hostname> to talk to each other.

docker logs rabbit-1

docker exec -it rabbit-1 bash

Once we got inside the container, we can use

rabbitmqctl
rabbitmq-plugins

Management plugins and Prometheus monitoring plugins are very useful.

To remove the container,

docker rm -f rabbit-1 

Then recreate the container,

docker run -d --rm --net rabbits -p 8080:15672 --hostname rabbit-1 --name rabbit-1 rabbitmq:3.8

Go back into the container and enable the management plugin,

rabbitmq-plugins enable rabbitmq_management

You can now browse at localhost:8080 and login using guest credentials. But this docker image is not showing stats. The official website recommends to use a correct image. Example,

# latest RabbitMQ 4.0.x
docker run -it --rm --net rabbits --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:4.0-management
FROM golang:1.23.3-alpine AS build

RUN apk add --no-cache git

WORKDIR /src

# Copy dependency files first
COPY go.mod go.sum ./

# Download dependencies
RUN go mod download

# Copy source code
COPY publisher.go ./

# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -o publisher

FROM alpine AS runtime

WORKDIR /app

COPY --from=build /src/publisher ./

CMD ["./publisher"]

Create publisher.go

package main

import (
	"fmt"
	amqp "github.com/rabbitmq/amqp091-go"
	"log"
	"net/http"
	"os"
	"time"
)

var rabbit_host = os.Getenv("RABBIT_HOST")
var rabbit_port = os.Getenv("RABBIT_PORT")
var rabbit_user = os.Getenv("RABBIT_USER")
var rabbit_password = os.Getenv("RABBIT_PASSWORD")

func main() {

	mux := http.NewServeMux()

	server := &http.Server{
		Addr:    ":80",
		Handler: mux,
	}

	mux.HandleFunc("POST /publish/{message}", submit)

	err := server.ListenAndServe()
	if err != nil {
		log.Fatalf("%s", err)
	}
	time.Sleep(time.Second)
}

func submit(writer http.ResponseWriter, request *http.Request) {
	message := request.PathValue("message")
	fmt.Println("Received messsage: " + message)

	conn, err := amqp.Dial("amqp://" + rabbit_user + ":" + rabbit_password + "@" + rabbit_host + ":" + rabbit_port + "/")

	if err != nil {
		log.Fatalf("%s: %s", "Failed to connnect to RabbitMQ", err)
	}

	defer conn.Close()

	ch, err := conn.Channel()

	if err != nil {
		log.Fatalf("%s: %s", "Failed to open a channel", err)
	}

	defer ch.Close()

	q, err := ch.QueueDeclare(
		"publisher", //name
		false,       //durable
		false,       // delete when unused
		false,       // exclusive
		false,       // no-wait
		nil,         // arguments
	)

	if err != nil {
		log.Fatalf("%s: %s", "Failed to declare a queue", err)
	}

	err = ch.Publish(
		"",     // exchange
		q.Name, // routing key
		false,  // mandatory
		false,  // immediate
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        []byte(message),
		})

	if err != nil {
		log.Fatalf("%s: %s", "Failed to publish a message", err)
	}

	fmt.Println("Published message successfully")
}

go mod init