skip to Main Content

Good morning,

I am facing a weird issue during the composing of my RabbitMQ container.

When I build the container without my python script, which creates the test structure of my RabbitMQ, it works fine. I access the container, run the script manually, and everything gets created perfectly, with no errors.

If I run the script with the same command ("python3 manager.py"), but in a RUN entry at the Dockerfile, it’s like it is suddenly unable to find the hostname or something like that during the RabbitMQ connector creation. So, it aborts the creation of the container.

I have tried executing it as a background Linux process, and the container is created, but the RabbitMQ structure creation keeps failing.

Docker-compose

version: "3.8"
services:
  rabbitmq:
    container_name: rabbitmq
    image: rabbitmq
    build: src/server/
    env_file:
      - src/server/server.env
    ports:
      - "15672:15672"
      - "5672:5672"
    hostname: rabbitmq
    networks:
      - rabbitmqnet

networks:
  rabbitmqnet:
    name: rabbitmqnet
    driver: bridge

Dockerfile

FROM rabbitmq:3-management
WORKDIR /app
EXPOSE 15672
COPY . /app
RUN apt-get update -y
RUN apt-get install -y python python3-pip
RUN pip install -r requirements.txt
RUN python3 manager.py

manager.py

import pika
import config

connection = pika.BlockingConnection(pika.ConnectionParameters(config.server, config.port, '/', pika.PlainCredentials(config.user, config.password)))
channel = connection.channel()

def main():
    createQueue("test-queue")
    createExchange("test-exchange")
    createBinding("test-exchange", "test-queue", "test")

# This method creates a queue.
def createQueue(qName):
    channel.queue_declare(queue=qName)

# This method creates an exchange.
def createExchange(eName):
    channel.exchange_declare(
        exchange=eName, 
        exchange_type='direct'
        )

# This method creates a binding routing key between an exchange and a queue. This allows the publisher to send messages to the queue through the exchange.
def createBinding(eName, qName, routingKey):
    channel.queue_bind(
        exchange=eName, 
        queue=qName, 
        routing_key=routingKey
        )

if __name__ == "__main__":
    main()

config.py

server= 'rabbitmq'
port= 5672
user= 'user'
password= 'password'

Error

[7/7] RUN python3 manager.py:
#0 0.276 Traceback (most recent call last):
#0 0.276   File "manager.py", line 4, in <module>
#0 0.276     connection = pika.BlockingConnection(pika.ConnectionParameters(config.server, config.port, '/', pika.PlainCredentials(config.user, config.password)))
#0 0.276   File "/usr/local/lib/python3.8/dist-packages/pika/adapters/blocking_connection.py", line 360, in init
#0 0.276     self._impl = self._create_connection(parameters, _impl_class)
#0 0.276   File "/usr/local/lib/python3.8/dist-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection
#0 0.276     raise self._reap_last_connection_workflow_error(error)
#0 0.276   File "/usr/local/lib/python3.8/dist-packages/pika/adapters/utils/selector_ioloop_adapter.py", line 565, in _resolve
#0 0.276     result = socket.getaddrinfo(self._host, self._port, self._family,
#0 0.276   File "/usr/lib/python3.8/socket.py", line 918, in getaddrinfo
#0 0.276     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
#0 0.276 socket.gaierror: [Errno -2] Name or service not known
failed to solve: executor failed running [/bin/sh -c python3 manager.py]: exit code: 1

2

Answers


  1. Chosen as BEST ANSWER

    Solved! I am so newbie with docker. the issue is that the image by default ends starting the RabbitMQ.

    So, if I executed with RUN the script, the container has not started nor the server, then for sure it cannot connect.

    Instead, when I used CMD, I was overriding the default initialization, so also the RabbitMQ did not ever start.

    Thank you!


  2. I think you need to use CMD or ENTRYPOINT instead of RUN in your dockerfile.
    Please read more about the topic: Difference between RUN and CMD in a Dockerfile

    RUN is an image build step, the state of the container after a RUN
    command will be committed to the container image. A Dockerfile can
    have many RUN steps that layer on top of one another to build the
    image.

    CMD is the command the container executes by default when you launch
    the built image. A Dockerfile will only use the final CMD defined. The
    CMD can be overridden when starting a container with docker run $image
    $other_command.

    ENTRYPOINT is also closely related to CMD and can modify the way a
    container starts an image.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search