Найти тему
Default Web development

Дружим docker контейнеры друг с другом

Представим достаточно частую ситуацию: Ваше приложение представляет собой несколько контейнеров.

Предположим следующий набор:

  1. Mariadb в роли БД (docker run --name db)
  2. Nuxt как фронтенд приложения (docker run --name front)
  3. Symfony как api бэкенд (docker run --name back)

Команда docker run выше представлена для примера имени контейнера. В реальных обстоятельствах флагов запуска будет больше. Имя необходимо присваивать, чтобы контейнеры могли опознавать друг друга по именам.

По отдельности они прекрасно работают, но ничего не знают друг о друге.

В ранних версиях docker можно было воспользоваться флагом --link {name} и связать контейнеры друг с другом. Ныне данная возможность не рекомендуется.

Популярным решением является docker compose. Однако, подобный подход требует запуска БД, nginx и приложения всегда отдельными инстансами. Чем больше приложений, тем больше экземпляров БД приходится запустить.

Наше теоретическое окружение имеет одну бд на N приложений.

По умолчанию, контейнеры запускаются в bridge сети. Но никакого dns резолвера нет. Создадим собственную сеть: docker network create dev.

Создается новая bridge сеть, но уже в ней работает встроенный в docker резолвер.

Контейнеры же теперь запускаются с флагом: --network dev.

Проверим доступность контейнеров: docker exec -it front bash. И уже изнутри контейнера ping back. Если пинги ходят - все настроено верно.

Мы добились того, что контейнеры знают друг друга по имени. Но мы все еще не имеем к ним доступа из Вашего браузера.

Существует множество решений данной проблемы:

docker inspect front - позволит узнать внутренний docker ip контейнера и прописать его в /etc/hosts. Способ требует постоянных ручных правок файла.

dnsmasq, bind9 - ставим их как локальный dns resolver и получаем доступ к контейнерам по их имени. Способ хороший, но требует сложной первичной настройки.

И самый простой, который отлично подойдет для локальной разработки.

docker run -d \
-v /var/run/docker.sock:/tmp/docker.sock \
-v /etc/hosts:/tmp/hosts \
dvdarias/docker-hoster

Данный контейнер получает доступ к вашему /etc/hosts и постоянно его обновляет, прослушивая события docker.sock. Если имя контейнера задано как front.dev - именно по нему он и будет доступен из браузера.

Таким образом мы добиваемся полноценного стека разработки, приложив для этого минимум усилий.

Рекомендовано к прочтению: