Последнее время часто сталкиваюсь с задачами, когда нужно объединить несколько проектов, каждый со своим docker-compose.yml, в одну общую сеть. За частую это связанно с тем, что микро сервисы разрабатывают разные команды, но они должны обменивать между собой и базой информацией. При этом сами проекты, за частую не настолько объемные, что бы держать всё это дело в Kubernetes.
Первый раз при реализации — пришлось погуглить, но как оказалось — внятных статей на эту тему не описано. Потому решил написать свою.
В целом задача не сложная и реализовать её можно по разному, в т.ч. сильно зависит от версии docker-compose которую вы используете. В статье рассмотрю работу на примере docker-compose v3.5
Дано:
— Два проекта со своими docker-compose.yml:
— В первом СУБД Postgress и самописный сервис, который обращается к базе
— Во втором просто сервис, который так же должен обращаться к базе выше
В версии 3.5 появилась удобная фишка network name
При указании имени сети — docker, при развертывании, попробует добавить контейнер в сеть с этим именем, а если такой сети нет — создаст.
Это удобно в том числе, если порядок развертывания для вас не важен, например в случае когда сервисы друг от друга не зависят напрямую.
Пример первого docker-compose.yml
Версия 3.5version: «3.5»services:
## Стандартный шаблон сервиса Postgres
postgres: image: postgres:12 command: postgres -c ‘max_connections=400’ volumes: — /srv/services/postgres/data:/var/lib/postgresql/data expose: — «5432» ports: — «5432:5432» environment: — POSTGRES_PASSWORD=**** — POSTGRES_USER=postgres — POSTGRES_DB=database_name
## Указываем алиас по которому контейнер будет виден в общей сети
networks: — postgress
## Описываем сферического коня в вакууме (самописный сервис)
service_1: image: service1_img:latest ports: — 1961:1961 — 8444:8444
## Конкретно он пусть зависит от запуска базы
depends_on: — postgres
## Передаем параметры подключения к базе
environment: — DB_URL=jdbc:postgresql://postgres:5432/database_name — DB_LOGIN=postgres — DB_PASSWORD=****
## Указываем алиас по которому контейнер будет виден в общей сети
networks: — service_1
## Описываем сети, каждому алиасу присваиваем одно имя сети
networks: postgress: name: network_name service_1: name: network_namefirst_project_docker-compose.ymlКопировать
А теперь опишем docker-compose.yml для второго сервиса, который так же должен попадать в сеть с именем network_name
## Версия 3.5
version: «3.5»services:
## Описываем второй сервис
service_2: image: service2_img:latest volumes: — /some/volume:/mount/somewhere ports: — 1962:1962
## Передаем параметры подключения к базе, как у сервиса_1
environment: — DB_URL=jdbc:postgresql://postgres:5432/database_name — DB_LOGIN=postgres — DB_PASSWORD=****
## Указываем алиас по которому контейнер будет виден в общей сети
networks: — service_2
## Присваиваем имя сети, как в соседнем файле.
networks: service_2: name: network_namesecond_project_docker-compose.ymlКопировать
На этом всё. Файлы можно запускать в разнобой с помощью docker-compose up -d
При запуске любого из них — будет создана сеть с именем «network_name», а второй подключиться в неё.
Дополнительно:
Если потребуется просто добавить контейнер в эту-же сетку, но без docker-compse — это можно выполнить с помощью команды:
docker run —network=network_name imagename:imageversionКопировать
Небольшая ремарка. Данная функция реализована в рамках одного хоста. Если вам требуется объединить контейнеры, которые крутятся на разных хостах — вам нужен docker swarm или kubernetes или любой другой аналогичный метод.
Полезные материалы по теме:
Официальная документация:
https://docs.docker.com/compose/compose-file/compose-file-v3/