Je veux exécuter RabbitMQ dans un conteneur et un processus de travail dans un autre. Le processus de travail doit accéder à RabbitMQ.
Je voudrais que ceux-ci soient gérés par docker-compose
.
C'est mon docker-compose.yml
fichier jusqu'à présent:
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
J'ai donc exposé les ports RabbitMQ. Le processus de travail accède à RabbitMQ à l'aide de l'URL suivante:
amqp://guest:guest@rabbitmq:5672/
C'est ce qu'ils utilisent dans le didacticiel officiel, mais localhost
a été remplacé par rabbitmq
, car les conteneurs doivent être détectable avec un nom d'hôte identique au nom du conteneur: =
Par défaut, Compose configure un réseau unique pour votre application. Chaque conteneur d'un service rejoint le réseau par défaut et est à la fois accessible par d'autres conteneurs sur ce réseau et détectable par eux à un nom d'hôte identique au nom du conteneur.
Chaque fois que je lance ceci, j'obtiens une erreur de connexion refusée:
Recreating ci_rabbitmq_1 ... done
Recreating ci_worker_1 ... done
Attaching to ci_rabbitmq_1, ci_worker_1
worker_1 | dial tcp 127.0.0.1:5672: connect: connection refused
ci_worker_1 exited with code 1
Je trouve cela intéressant car il utilise l'IP 127.0.0.1
qui (je pense) est localhost
, même si j'ai spécifié rabbitmq
comme nom d'hôte. Je ne suis pas un expert en réseautage docker, alors peut-être que cela est souhaité.
Je suis heureux de fournir plus d'informations si nécessaire!
Modifier
Il y a une question presque identique ici . Je pense que je dois attendre que rabbitmq
soit opérationnel avant de démarrer worker
. J'ai essayé de le faire avec un bilan de santé:
version: "2.1"
services:
rabbitmq:
image: rabbitmq
command: rabbitmq-server
expose:
- "5672"
- "15672"
healthcheck:
test: [ "CMD", "nc", "-z", "localhost", "5672" ]
interval: 10s
timeout: 10s
retries: 5
worker:
build: .
depends_on:
rabbitmq:
condition: service_healthy
(Notez la version différente). Cela ne fonctionne pas, cependant - il échouera toujours car il n'est pas sain.
Ah! Je l'ai corrigé. @Ijaz était tout à fait correct - le service RabbitMQ prend du temps à démarrer et mon collaborateur essaie de se connecter avant de fonctionner.
J'ai essayé d'utiliser un délai, mais cela a échoué lorsque le RabbitMQ a pris plus de temps que d'habitude.
Cela indique également un problème architectural plus important - que se passe-t-il si le service de mise en file d'attente (RabbitMQ dans mon cas) se déconnecte pendant la production? En ce moment, mon site entier échoue. Il doit y avoir une redondance et une interrogation intégrées.
Comme décrit ceci cette réponse connexe , nous pouvons utiliser des contrôles de santé dans 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
Maintenant, le conteneur worker
redémarrera plusieurs fois tandis que le conteneur rabbitmq
restera malsain. rabbitmq
devient immédiatement sain lorsque nc -z localhost 5672
réussit - c'est-à-dire lorsque la file d'attente est active!
Vous n'avez peut-être pas besoin d'exposer/mapper les ports sur l'hôte si vous accédez simplement au service à partir d'un autre conteneur.
De la documentation:
Expose Exposez les ports sans les publier sur la machine hôte - ils ne seront accessibles qu'aux services liés. Seul le port interne peut être spécifié.
expose: - "3000" - "8000"
Donc ça devrait être comme ça:
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
assurez-vous également de vous connecter à rabitmq uniquement lorsqu'il est prêt à être serveur sur le port.