Connecting to RabbitMQ from one Docker stack to another results in Connection Timed Out

Viewed 33

I am trying to publish messages from a PHP (Laravel) application to a RabbitMQ queue, which is then consumed by a .NET application. All of this is hosted in a pair of Docker stacks (via docker-compose), named main and report and structured like so:-

  • main stack
    • php PHP Application service
  • report stack
    • handler .NET Application service
    • queue RabbitMQ service

I can get the report_queue IP from either docker inspect or the RabbitMQ logs, and store it in my PHP app's .env and then php artisan config:cache. However, when I am attempting to connect from main_php to report_queue (using php-amqplib/php-amqplib) with...

new AMQPStreamConnection('10.0.2.25', 5672, 'report', 'obviouslynottherealpassword');

...it will always return the following error:-

stream_socket_client(): unable to connect to tcp://10.0.2.25:5672 (Connection timed out)

So it seems that it can't reach the queue service, yet from main_php I can both ping the queue IP and connect to 10.0.2.25:5672 via telnet just fine! Even when I add a retry mechanism, it will give the same error. Even if I destroy (rm) both stacks, re-deploy, update IP in .env and config:cache - Same issue!

All queue connections from the .NET service (sat on the same stack) work perfectly fine, but connection attempts from the PHP service don't even seem to touch RabbitMQ (nothing appears in the logs). The user/password are definitely correct, as they are copied from .NET.

I couldn't find anything that describes my issue in the php-amqplib issue tracker or elsewhere on SO. My connection code is more-or-less a straight copy from some of the most basic examples php-amqplib provide. Docker-wise, my understanding is that the networks setup in my main and report docker-compose files should allow services within those networks to communicate. I have also tried explicitly adding networks: - default to the report_queue service, but got the exact same error.

Can anyone see where I'm going wrong? My understanding is that everything here should work, but it doesn't!

The following are the relevant bits of code, for reference.

docker-compose.main.yml:-

version: "3.9"

networks:
  default:
    attachable: true
    driver: overlay

services:
  php:
    hostname: php
    working_dir: /var/www/html
    volumes:
      - ~/code/publisher:/var/www/html:cached
    image: publisher:latest # (custom docker image)
    env_file:
      - localhost.env

The main stack is brought up with docker stack deploy -c docker-compose.main.yml --with-registry-auth local --prune

docker-compose.report.yml:-

version: "3.9"

networks:
  default:
    external: true
    name: main_default

services:
  handler:
    hostname: handler
    image: handler:latest # (custom docker image)
    restart: unless-stopped
    ports:
      - "5000:80"
      - "5001:443"
    env_file: ./dotenvs/handler.env
    extra_hosts:
      - host.docker.internal:host-gateway
  queue:
    image: rabbitmq:3-alpine
    ports:
      - "5672:5672"
    volumes:
      - ./config/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf

dotenvs/handler.env:-

RABBITMQ_HOST=report_queue
RABBITMQ_USER=report
RABBITMQ_PASSWORD=obviouslynottherealpassword

config/rabbitmq.conf:-

default_user = report
default_pass = obviouslynottherealpassword

The report stack is brought up with docker stack deploy -c docker-compose.report.yml report

The code that attempts connection from main_php (extracted from a Laravel 7 command) is:-

$request = [
    'report_name': 'all-the-data',
    'date': '2022-01-01'
];

$amqpConnection = new AMQPStreamConnection(env('REPORT_QUEUE_HOST'), 5672, 'report', 'obviouslynottherealpassword');

// doesn't reach anything past this point due to error

// ...

And the .env PHP is consuming:-

REPORT_QUEUE_HOST=10.0.2.25

And the complete resulting error:-

[2022-09-16 10:13:52] local.ERROR: stream_socket_client(): unable to connect to tcp://10.0.2.25:5672 (Connection timed out) 
[object] (PhpAmqpLib\\Exception\\AMQPIOException(code: 0): stream_socket_client(): unable to connect to tcp://10.0.2.25:5672 (Connection timed out) at /home/me/code/publisher/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php:108)
[stacktrace]
#0 /home/me/code/publisher/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Connection/AbstractConnection.php(253): PhpAmqpLib\\Wire\\IO\\StreamIO->connect()
#1 /home/me/code/publisher/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Connection/AbstractConnection.php(236): PhpAmqpLib\\Connection\\AbstractConnection->connect()
...
#16 /home/me/code/publisher/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(129): Illuminate\\Console\\Application->run()
#17 /home/me/code/publisher/artisan(35): Illuminate\\Foundation\\Console\\Kernel->handle()
#18 {main}


   PhpAmqpLib\Exception\AMQPIOException 

  stream_socket_client(): unable to connect to tcp://10.0.2.25:5672 (Connection timed out)

Also, in case it's relevant: I'm using IP because using report_queue by hostname from main_php results in Temporary failure in name resolution instead of Connection timed out. So I chose to keep things simple and just use the IP.

0 Answers
Related