Как / можно ли избежать дублирования частей Docker, составляющих файл из нескольких взаимозависимых проектов? - PullRequest
1 голос
/ 10 октября 2019

Давайте возьмем, например, мобильное приложение, которое зависит от двух или более API.

Каждый из этих проектов разделен в независимых репозиториях Git. Затем у нас есть 3 репозитория, которые позволяют нам разрабатывать каждый параллельно.

Каждый проект имеет свои собственные зависимости:

  • Первый API, например, требует базу данных SQL
  • Второй API, требует базы данных NoSQL
  • Мобильное приложение требует этих двух API

Теперь я хочу "докеризировать" все эти проекты, чтобы упростить среду разработки и объединить ее между разработчикамии / или производственная среда.

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

Например, в первом API

version: "3.7"

services:
  first_api:
    image: golang:1.13
    working_dir:
      - /src
    depends_on:
      - mysql
    volumes:
      - ".:/src"
    command: go run main.go

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_USER_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE_NAME}

  adminer:
    image: adminer
    restart: always

Второй API будет иметь аналогичный файл docker-compose.yml, но вместо него будет использоваться NoSQL DB.

Тогда в репозитории мобильных приложений будет файл docker-compose.yml с большим количеством дублирующегося кода (и точно такими же контейнерами). ) из-за его взаимозависимости с двумя другими API, некоторые другие файлы идентичны (например, .env файлы, сценарии точки входа при необходимости ...).

Базы данныхнастройка / заполнение будет также выполняться в 2 репозиториях, что может немного раздражать.

Файл docker-compose.yml будет выглядеть примерно так:

version: "3.7"

services:
  app:
    build:
      context: .
      args:
        - IP=${IP}
    ports:
      - 19000:19000
      - 19001:19001
      - 19002:19002
    volumes:
      - ".:/app"
    depends_on:
      - first-api
      - second-api

  first-api:
    image: my-registry:5000/first-api
    ports:
      - 9009:3000
    depends_on:
      - mysql
    volumes:
      - ".env:/dist/.env"

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_USER_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE_NAME}

  adminer:
    image: adminer
    restart: always
    ports:
      - 9099:8080

  second-api:
    image: my-registry:5000/second-api
    ports:
      - 9010:3000
    depends_on:
      - mongo

  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_ROOT_USERNAME}
      ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_ROOT_PASSWORD}

Фактически в этомВ конечном файле docker-compose у нас есть 4 идентификатора контейнера, полностью идентичные им внутри конфигураций API, у нас также есть несколько переменных среды, дублированных и версированных минимум в 2 репозиториях.

Иногда мы можем также дублировать Dockerfile, в соответствии сконкретные случаи, настройка БД или что-то еще.

Я что-то упустил в этой настройке среды разработки Docker, которая позволила бы мне избежать некоторого дублирования?

Есть ли рекомендация или рекомендацияКак избежать этого?

Как компании с большой взаимозависимой архитектурой микросервисов управляют этой взаимозависимостью?

Ответы [ 2 ]

0 голосов
/ 11 октября 2019

Я бы, вероятно, настроил это, независимо запустив файлы Docker Compose двух ваших сервисов, а затем запустив прокси-сервер впереди, который связывает их вместе. Вы можете «позаимствовать» сети из других docker-compose.yml файлов. У вас более или менее есть это сейчас;прокси будет вашим контейнером «приложения», и вы можете использовать external: ссылку на default сети других приложений.

version: '3'
services:
  app:
    build: .
    environment:
      - IP=${IP}
    ports:
      - 19000:19000
      - 19001:19001
      - 19002:19002
    networks:
      - firstapi_default
      - secondapi_default
networks:
  firstapi_default:
    external: true
  secondapi_default:
    external: true

Этот подход также работает, если у вас естьнесколько сервисов, каждый из которых независимо нуждается в базе данных MySQL;запуск отдельной docker-compose up в каждом каталоге проекта создаст новую отдельную базу данных для каждого. (В микросервисной архитектуре вы обычно не разделяете хранилища данных между сервисами; они обмениваются данными только через свои API.)

При этом вы довольно быстро столкнетесь с проблемой масштабирования, если одна из ваших внутренних служб должна вызвать другую. и Docker Compose не может быть правильным инструментом для этого. Kubernetes является значительным обязательством, но оно позволит вам развернуть каждую из этих отдельных служб в отдельном пространстве имен, а затем использовать DNS-имена, такие как first_api.first_namespace.svc.cluster.local, для связи между ними.

0 голосов
/ 10 октября 2019

Вы можете использовать якоря и псевдонимы YAML с полями расширения docker-compose .

Вот еще две статьи с полезными подробностями об этом:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...