Контейнеры общего строителя в Docker или Docker Compose - PullRequest
0 голосов
/ 02 марта 2020

Мой проект структурирован примерно так:

project
|- docker_compose.yml
|- svc-a
   |- Dockerfile
|- svc-b
   |- Dockerfile
|- common-lib
   |- Dockerfile

Внутри docker_compose.yaml:

version: 3.7
services:
  common-lib:
    build:
      context: ./common-lib/
    image: common-lib:latest
  svc-a:
    depends_on:
      - common-lib
    build:
       ...
  svc-b:
    depends_on:
      - common-lib
    build:
      ...

В common-lib/Dockerfile относительно стандартно:

FROM someBuilderBase:latest
COPY . .
RUN build_libraries.sh

Затем в svc-a/Dockerfile я импортирую эти встроенные библиотеки:

FROM common-lib:latest as common-lib

FROM someBase:latest
COPY --from=common-lib ./built ./built-common-lib
COPY . .
RUN build_service_using_built_libs.sh

И Dockerfile для sv c -b в основном такой же.

Это прекрасно работает при использовании docker-compose build svc-a как Сначала он создает контейнер common-lib из-за этого depends-on, и я могу легко ссылаться на него с помощью common-lib:latest. Это также здорово, потому что запуск docker-compose build svc-b не перестраивает эту базовую общую библиотеку.

Моя проблема в том, что я определяю контейнер компоновщика как docker compose service. Когда я запускаю docker-compose up, он пытается запустить common-lib как работающий бинарный файл / сервис и выдает множество ошибок. В моем реальном проекте у меня есть цепочка этих сервисов контейнеров-строителей , что делает docker-compose up непригодным для использования.

Я относительно новичок в docker, есть ли более канонический способ сделать это, в то время как а) избегая дублирования кода, создающего common-lib в нескольких Dockerfiles, и б) избегая ручного повторного запуска docker build ./common-lib перед запуском docker build ./svc-a (or b)?

1 Ответ

0 голосов
/ 02 марта 2020

То, как вы это делаете, это не совсем как вы должны это сделать в Docker.

У вас есть два варианта для достижения того, что вы хотите:

1 / Многоступенчатая сборка

Это почти то, что вы делаете с этой строкой (в вашем svc-a файле docker)

FROM common-lib:latest as common-lib

Однако вместо создания вашего common-lib изображения в другом проект, просто скопируйте содержимое файла dockerfile в свой сервис:

FROM someBuilderBase:latest as common-lib
COPY . .
RUN build_libraries.sh

FROM someBase:latest
COPY --from=common-lib ./built ./built-common-lib
COPY . .
RUN build_service_using_built_libs.sh

Таким образом, вам не нужно добавлять сервис common-lib в docker -compose.

2 / Наследование

Если у вас много изображений, которым нужно использовать то, что находится внутри вашего common-lib (и вы не хотите добавлять его в каждый докер-файл с многоступенчатой ​​сборкой), тогда вы можете просто использовать наследование.

Что такое наследование в docker?

Это базовое изображение .
Из вашего примера svc-a изображение основано на someBase:latest. Я думаю, это то же самое для svc-b. В этом случае просто добавьте нужную библиотеку в someBase образе (например, с многоступенчатой ​​сборкой или созданием базового образа, содержащего вашу библиотеку).

...