multi-stage build in docker compose?

Refresh

January 2019

Views

411 time

1

How can I specify multi-stage build with in a docker-compose.yml?

For each variant (e.g. dev, prod...) I have a multi-stage build with 2 docker files:

  • dev: Dockerfile.base + Dockerfile.dev
  • or prod: Dockerfile.base + Dockerfile.prod

File Dockerfile.base (common for all variants):

FROM python:3.6
RUN apt-get update && apt-get upgrade -y
RUN pip install pipenv pip
COPY Pipfile ./
# some more common configuration...

File Dockerfile.dev:

FROM flaskapp:base
RUN pipenv install --system --skip-lock --dev
ENV FLASK_ENV development
ENV FLASK_DEBUG 1

File Dockerfile.prod:

FROM flaskapp:base
RUN pipenv install --system --skip-lock
ENV FLASK_ENV production

Without docker-compose, I can build as:

# Building dev
docker build --tag flaskapp:base -f Dockerfile.base .
docker build --tag flaskapp:dev -f Dockerfile.dev .
# or building prod
docker build --tag flaskapp:base -f Dockerfile.base .
docker build --tag flaskapp:dev -f Dockerfile.dev .

According to the compose-file doc, I can specify a Dockerfile to build.

# docker-compose.yml
version: '3'
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate

But how can I specify 2 Dockerfiles in docker-compose.yml (for multi-stage build)?

1 answers

3

Как уже упоминалось в комментариях, многоступенчатый Постройте включает один Dockerfile выполнить несколько этапов. Что у вас есть общее базовое изображение.

Вы можете преобразовать их в нетрадиционную многоступенчатой ​​сборку с синтаксисом (я говорю нетрадиционным, потому что вы не выполняете какое-либо копирования между слоями и вместо того, чтобы использовать только из линии, чтобы выбрать из предыдущего этапа):

FROM python:3.6 as base
RUN apt-get update && apt-get upgrade -y
RUN pip install pipenv pip
COPY Pipfile ./
# some more common configuration...

FROM base as dev
RUN pipenv install --system --skip-lock --dev
ENV FLASK_ENV development
ENV FLASK_DEBUG 1

FROM base as prod
RUN pipenv install --system --skip-lock
ENV FLASK_ENV production

Тогда вы можете построить один этап или другой , используя --targetсинтаксис для создания, или создания сообщения файла , как:

# docker-compose.yml
version: '3.4'
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile
      target: prod

Самым большим недостатком является текущая сборка двигателя будет пройти через каждый этап, пока он не достигнет цели. Строить кэширование может означать, что это только к югу от второго процесса. И BuildKit, который выходит из экспериментальной в 18.09 и будет нуждаться вверх по течению от поддержки Докер-композе будет умнее о только выполнив необходимые команды, чтобы получить желаемый целевой встроенный.

Все , что сказал, я считаю , что это пытается вписаться квадратный колышек в круглое отверстие. Разработчик докер-Compose поощряет пользователей отойти от выполнения сборки в файле создания письма себя , так как она не поддерживается в режиме роя. Вместо этого рекомендуется решение для выполнения сборки с сервером сборки CI / CD и раздвинуть эти изображения в реестр. Затем вы можете запустить тот же файл с созданием сообщения docker-composeили docker stack deployили даже некоторые K8S эквивалентов, без необходимости перепроектировать процесс.