Docker для локальной разработки с несколькими средами

#docker #docker-compose #dockerfile #microservices

#docker #docker-compose #dockerfile #микросервисы

Вопрос:

Я ищу использование docker для эмуляции минимума нашей текущей облачной среды. У нас есть около 10 сервисов (каждый со своей собственной базой данных MySQL8, redis, php-fpm и nginx). В настоящее время у них есть docker-compose.yml репозиторий для каждого, но они не могут общаться друг с другом, если я хочу протестировать функцию, в которой службе нужно общаться с другим, мне не повезло.

Мой первый подход состоял в том, чтобы создать службу для Dockerfile каждого сервиса (и запустить все вместе, используя новый docker-compose.yml ), используя Debian, но я не продвинулся слишком далеко, смог установить nginx ( php-fpm и зависимости), но когда я добрался до баз данных, это стало странным, и у меня возникло ощущение, что это не тотправильный способ сделать это.

Есть ли способ docker-compose.yml «включить» каждую docker-compose.yml из служб? Есть ли лучший подход к этому? Или я должен просто продолжать Dockerfile и запускать их все в одной сети, используя docker-compose ?

Комментарии:

1. Вы можете настроить docker-compose с использованием external сетей , т.Е. Проект A создается с помощью сети A, затем создается проект B, который использует свою собственную сеть внешнюю сеть, созданную проектом A. Службы из проекта B, настроенные с помощью внешней сети, могут взаимодействовать со службами, работающими в проекте A.

2. Если вы хотите подключить все службы к одной сети (при условии, что все они настроены с использованием сети по умолчанию), вы можете использовать -f параметр командной строки или переменную COMPOSE_FILE среды для включения служб из всех docker-compose.yml файлов, т.е.: COMPOSE_FILE=docker-compose.a.yml:docker-compose.b.yml docker-compose up -d однако имейте в виду, что это будет работать как переопределение, если несколько проектовукажите одну и ту же службу.

Ответ №1:

TL; DR;

Вы можете настроить docker-compose использование external сетей для связи со службами из других проектов или (в зависимости от вашего проекта) использовать -f параметр командной строки / COMPOSE_FILE переменную среды, чтобы указать путь к файлам (файлам) компоновки и подключить все службы к одной сети.


Использование внешних сетей

Учитывая приведенное ниже tree с проектом a и b :

 .
├── a
   └── docker-compose.yml
└── b
    └── docker-compose.yml
  

Project a docker-compose задает имя для сети по умолчанию:

 version: '3.7'
services:
  nginx:
    image: 'nginx'
    container_name: 'nginx_a'
    expose:
    - '80'
networks:
  default:
    name: 'net_a'
  

И проект b настроен на использование именованной сети net_b и уже существующей net_a внешней сети:

 version: '3.7'
services:
  nginx:
    image: 'nginx'
    container_name: 'nginx_b'
    expose:
    - '80'
    networks:
    - 'net_a'
    - 'default'
networks:
  default:
    name: 'net_b'
  net_a:
    external: true
  

exec ‘ing в nginx_b контейнер, мы можем добраться до nginx_a контейнера:

связь с внешней сетевой службой

Примечание: это минималистичный пример. Внешняя сеть должна существовать, прежде чем пытаться вызвать среду, настроенную с использованием уже существующей сети. Вместо того, чтобы изменять существующие проекты docker-compose.yml , я бы предложил использовать переопределения.

Конфигурация предоставляет nginx_b контейнеру опору внутри обеих сетей:

создание IP-адресов служб

Использование опции -f командной строки

Использование параметра -f командной строки действует как переопределение. Он не будет работать с вышеупомянутыми файлами компоновки, поскольку оба указывают nginx службу ( docker-compose переопределит / объединит первую nginx службу со второй).

Использование модифицированного docker-compose.yml для проекта a :

 version: '3.7'
services:
  nginx_a:
    container_name: 'nginx_a'
    image: 'nginx'
    expose:
    - '80'
  

… и для проекта b :

 version: '3.7'
services:
  nginx_b:
    image: 'nginx'
    container_name: 'nginx_b'
    expose:
    - '80'
  

… мы можем подключить обе среды к одной сети: docker-compose -f a/docker-compose.yml:b/docker-compose.yml up -d :

-опция командной строки f

Комментарии:

1. Спасибо за ответ. Я решил использовать метод -f. Единственная проблема, которую я обнаружил, заключается в том, что mysql из службы A выходит из строя с MySQL службы B. С сообщением об ошибке: Unable to lock ./ibdata1 error: 11

2. Обе службы используют один и тот же именованный том (?), Похоже, что в этом случае первый экземпляр запускается правильно, а второй (монтирующий тот же том) не может получить блокировку, которая удерживается первой службой.

3. Вы используете привязку-монтирование из локальной файловой системы, а не именованные тома. Вы можете обновить сопоставления томов для каждой из служб БД, чтобы использовать именованный том или использовать другой путь на хосте. т. е. Заменить ./env/mysql/data:/var/lib/mysql на ./db_a/mysql/data:/var/lib/mysql для одной из служб, ./db_b/mysql/data:/var/lib/mysql чтобы службы не пытались смонтировать один и тот же каталог.

4. Да, но путь ./env/mysql/data указан относительно того места, где docker-compose up выполняется iirc (мне нужно было бы перепроверить). Идея есть, хотя, пока эти службы не монтируют один и тот же том, у вас все должно быть хорошо.

5. Я просто запускаю пару тестов, и путь ./env/mysql/data указан относительно первого docker-compose.yml расположения файла (передается с аргументом -f), что выдает ошибку: build path ...service_aservice_b.. either does not exist, is not accessible, or is not a valid URL