Вопрос или проблема
Я пытаюсь подключить веб-приложение, развернутое в одном контейнере, к rabbitmq, развернутому в другом контейнере.
Основываясь на этом подключении к контейнеру RabbitMQ с помощью docker-compose, я создал следующий docker-compose:
version: '3'
services:
webapp:
container_name: chat
build:
context: .
depends_on:
- broker
ports:
- "8080:8080"
broker:
container_name: rabbit_chat
image: rabbitmq
command: rabbitmq-server
expose:
- 5672
- 15672
healthcheck:
test: ["CMD", "curl", "-f", "http://broker:5672"]
interval: 30s
timeout: 10s
retries: 5
webapp – это сервис веб-приложения, в котором я задаю следующие свойства rabbitmq:
host = broker
port = 15672
login = guest
password = guest
Я выбрал ‘broker’ в качестве хоста, так как в документации рекомендуется подключать контейнеры по умолчанию с использованием имени сервиса в docker-compose.
И это не работает. Также я пробовал использовать “localhost” в качестве хоста для подключения.
Кроме того, inspecting контейнер “rabbit_chat”, я вижу в выводе:
"Log": [
{
"Start": "2020-04-11T14:54:25.0988242Z",
"End": "2020-04-11T14:54:25.2920557Z",
"ExitCode": -1,
"Output": "OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused \"exec: \\\"curl\\\": executable file not found in $PATH\": unknown"
}
Попробуйте сеть:
services:
webapp:
...
networks:
- mynetwork
broker:
...
networks:
- mynetwork
networks:
mynetwork:
Это также настраивает внутренний DNS, так что вы действительно можете использовать broker
в качестве имени хоста в webapp
для обращения к другому контейнеру.
Из ваших комментариев похоже, что это проблемы с авторизацией доступа, а не проблемы с портами docker.
Сначала попробуйте выполнить curl изнутри контейнера rabbit-mq,
Из лога выглядит так, что у вас не установлен curl в контейнере rabbit, поэтому установите его и попробуйте.
Затем попробуйте снаружи (с вашего компьютера):
Просто сопоставьте порты в контейнере rabbit: “5672:5672” и “15672:15672”.
curl localhost:5672 (или выполните docker inspect и выполните curl напрямую на ip-адрес контейнера).
Собраны ли образы из одного базового изображения? Возможно, у вас есть ufw в образе rabbit.
Также попробуйте отключить ufw на вашем компьютере и проверьте (если он есть).
Лучший способ общения между контейнерами в docker-compose – через сетевой мост, поэтому в конечном итоге вам придется его использовать.
Ответ или решение
Соединение двух контейнеров Docker через Docker Compose
Когда вы работаете с контейнерами Docker, одним из основных аспектов является возможность взаимодействия между ними. На вашем примере веб-приложение (webapp) подключается к RabbitMQ (broker). Давайте разберем, как правильно установить это соединение с использованием docker-compose
.
Корректная структура docker-compose
На этапе конфигурации вашего docker-compose.yml
файла, вы уже на правильном пути, но есть несколько моментов, на которые стоит обратить внимание. Ниже представлена улучшенная версия вашего файла docker-compose.yml
:
version: '3.8'
services:
webapp:
container_name: chat
build:
context: .
depends_on:
- broker
ports:
- "8080:8080"
networks:
- mynetwork
broker:
container_name: rabbit_chat
image: rabbitmq:management
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
networks:
- mynetwork
networks:
mynetwork:
Объяснение конфигурации
-
Сервисы и сети: Мы определили обе службы (
webapp
иbroker
) в одну и ту же сеть (mynetwork
). Это позволяет контейнерам взаимодействовать друг с другом через внутренний DNS, используя имя сервиса. В вашем случае, имяbroker
должно использоваться в конфигурации подключения RabbitMQ. -
Порты: Обратите внимание на то, что RabbitMQ по умолчанию использует порты 5672 и 15672 для AMQP и интерфейса управления соответственно. Мы открыли эти порты, чтобы иметь возможность обращаться к RabbitMQ как извне, так и из других контейнеров.
-
Переменные окружения: Вместо того чтобы полагаться на значения по умолчанию, полезно явно задавать пользователя и пароль для RabbitMQ через переменные окружения. Это не только повышает безопасность, но и облегчает дальнейшую эксплуатацию.
Проверка подключения
После того как ваше приложение будет запущено с помощью команды docker-compose up
, вам нужно будет удостовериться, что контейнеры могут обмениваться данными. Вот несколько шагов:
-
Проверка соединения из контейнера: Войдите в контейнер RabbitMQ, чтобы протестировать соединение через
curl
. Для этого можно выполнить команду:docker exec -it rabbit_chat /bin/bash
Затем внутри контейнера выполните:
curl http://broker:15672
Если
curl
не установлен, добавьте его с помощью:apt-get update && apt-get install -y curl
-
Тестирование подключения к локальному хосту: Вы также можете протестировать доступ к RabbitMQ из командной строки вашего хоста:
curl http://localhost:15672
-
Проверка логов: Если что-то пойдет не так, посмотрите логи контейнера RabbitMQ с помощью:
docker logs rabbit_chat
Заключение
Следуя этим рекомендациям, вы сможете без проблем наладить связь между вашим веб-приложением и RabbitMQ. Убедитесь, что все контейнеры работают в одной сети и что используемые вами порты и учетные данные правильно настроены. Приложив немного усилий на начальном этапе, вы значительно упростите себе дальнейшую разработку и поддержку вашего приложения.