Connecting to RabbitMQ container with docker-compose
Aha! I fixed it. @Ijaz was totally correct - the RabbitMQ service takes a while to start, and my worker tries to connect before it's running.
I tried using a delay, but this failed when the RabbitMQ took longer than usual.
This is also indicative of a larger architectural problem - what happens if the queuing service (RabbitMQ in my case) goes offline during production? Right now, my entire site fails. There needs to be some built-in redundancy and polling.
As described this this related answer, we can use healthchecks in docker-compose 3+
:
version: "3"services: rabbitmq: image: rabbitmq command: rabbitmq-server expose: - 5672 - 15672 healthcheck: test: [ "CMD", "nc", "-z", "localhost", "5672" ] interval: 5s timeout: 15s retries: 1 worker: image: worker restart: on-failure depends_on: - rabbitmq
Now, the worker
container will restart a few times while the rabbitmq
container stays unhealthy. rabbitmq
immediately becomes healthy when nc -z localhost 5672
succeeds - i.e. when the queuing is live!
Maybe you dont need to expose/map the ports on the host if you are just accessing the service from another container.
From the documentation:
Expose Expose ports without publishing them to the host machine - they’ll only be accessible to linked services. Only the internal port can be specified.
expose: - "3000" - "8000"
So it should be like this:
version: "3"services: rabbitmq: image: rabbitmq command: rabbitmq-server expose: - "5672" - "15672" worker: build: ./worker depends_on: - rabbitmq # Allow access to docker daemon volumes: - /var/run/docker.sock:/var/run/docker.sock
also make sure to connect to rabitmq only when its ready to server on port.
Here is the correct working example :
version: "3.8" services: rabbitmq: image: rabbitmq:3.7.28-management #container_name: rabbitmq volumes: - ./etc/rabbitmq/conf:/etc/rabbitmq/ - ./etc/rabbitmq/data/:/var/lib/rabbitmq/ - ./etc/rabbitmq/logs/:/var/log/rabbitmq/ environment: RABBITMQ_ERLANG_COOKIE: ${RABBITMQ_ERLANG_COOKIE:-secret_cookie} RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-admin} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-admin} ports: - 5672:5672 #amqp - 15672:15672 #http - 15692:15692 #prometheus healthcheck: test: [ "CMD", "rabbitmqctl", "status"] interval: 5s timeout: 20s retries: 5 mysql: image: mysql restart: always volumes: - ./etc/mysql/data:/var/lib/mysql - ./etc/mysql/scripts:/docker-entrypoint-initdb.d environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: mysqldb MYSQL_USER: ${MYSQL_DEFAULT_USER:-testuser} MYSQL_PASSWORD: ${MYSQL_DEFAULT_PASSWORD:-testuser} ports: - "3306:3306" healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] timeout: 20s retries: 10 trigger-batch-process-job: build: . environment: - RMQ_USER=${RABBITMQ_DEFAULT_USER:-admin} - RMQ_PASS=${RABBITMQ_DEFAULT_PASS:-admin} - RMQ_HOST=${RABBITMQ_DEFAULT_HOST:-rabbitmq} - RMQ_PORT=${RABBITMQ_DEFAULT_PORT:-5672} - DB_USER=${MYSQL_DEFAULT_USER:-testuser} - DB_PASS=${MYSQL_DEFAULT_PASSWORD:-testuser} - DB_SERVER=mysql - DB_NAME=mysqldb - DB_PORT=3306 depends_on: mysql: condition: service_healthy rabbitmq: condition: service_healthy