Docker-compose.yml файл, который строит базовый образ, потом дочерние на его основе?

Для пояснения, когда я говорю базовое изображение, я имею в виду родительское изображение, которое имеет все общие конфигурации, так что дочерним элементам на его основе не нужно загружать зависимости по отдельности.

Насколько я понимаю, файлы docker-compose.yml являются конфигурациями времени выполнения, а файлы Docker - конфигурациями времени сборки. Тем не менее, есть build вариант с использованием docker-compose, и мне было интересно, как я могу использовать это для создания базового образа.

На данный момент я использую сценарий оболочки, который запускает другие сценарии оболочки. Один строит все мои изображения из базового изображения, которое он также создает. Другой запускает их как контейнеры с необходимыми конфигурациями. Однако базовое изображение никогда не запускается как контейнер.

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

echo "Creating docker network net1"
docker network create net1

echo "Running api as a container with port 5000 exposed on net1"
docker run --name api_cntr --net net1 -d -p 5000:5000 api_img

echo "Running redis service with port 6379 exposed on net1"
docker run --name message_service --net net1 -p 6379:6379 -d redis

echo "Running celery worker on net1"
docker run --name celery_worker1 --net net1 -d celery_worker_img

echo "Running flower HUD on net1 with port 5555 exposed"
docker run --name flower_hud --net net1 -d -p 5555:5555 flower_hud_img

Скрипт, который делает изображения, выглядит следующим образом:

echo "Building Base Image"
docker build -t base ../base-image

echo "Building api image from Dockerfile"
docker build -t api_img  ../api

echo "Building celery worker image"
docker build -t celery_worker_img ../celery-worker

echo "Building celery worker HUD"
docker build -t flower_hud_img ../flower-hud

Мои вопросы сводятся к одному: могу ли я создать этот базовый образ, даже не запуская его в контейнере с помощью docker-compose. (Все Dockerfiles начинаются с FROM base:latest кроме самой базы). Я стараюсь сделать это как можно более легким для других людей, чтобы им нужно было выполнить только одну команду.

РЕДАКТИРОВАТЬ: я использую версию 3, и в соответствии с документами, build: игнорируется, а docker-compose принимает только предварительно созданные изображения.

6 ответов

Решение

Согласно документации build опция сервиса принимает каталог в качестве аргумента, который содержит известный Dockerfile, Невозможно создать базовый образ, а затем фактический образ сервиса.

Docker - это среда, в которой работает ваше приложение. Когда вы создаете базовый образ, у него должны быть вещи, которые не будут часто меняться. Затем вам нужно собрать baseiamge один раз, загрузить в свой репозиторий и использовать FROM baseimage:latest в Dockerfile.

Например, если вы создаете приложение Python, вы можете создать его из Python и установить требования:

FROM python:3.6
COPY requirements.txt .
RUN pip install -r requirements.txt

Вот, python:3.6 это базовый образ, который не будет часто меняться, поэтому вам не нужно собирать его каждый раз, когда вы запускаете команды docker compose.

Проведя небольшое исследование, основанное на ответе @amiasato, похоже, что существует replicatedключ, который вы можете установить на 0вот так:

      version: "3"
services:
  base-image:
    build:
      context: .
      dockerfile: Dockerfile-base
    deploy:
      mode: replicated
      replicas: 0

См. https://docs.docker.com/compose/compose-file/compose-file-v3/#replicas .

Да вроде. Используйте это так:

version: '2'

services:

    wls-admin:
        container_name: wls-admin
        image: weblogic-domain
        build:
            context: wls-admin
            args:
                - ADMIN_PORT=${WLS_ADMIN_PORT}
                - CLUSTER_NAME=${WLS_CLUSTER_NAME}
                - PRODUCTION_MODE=dev
        networks:
            - wls-network

image пункт здесь делает docker-compose build создать образ докера с именем weblogic-domain за эту услугу. Этот образ может быть повторно использован Dockerfiles других сервисов, даже в том же процессе сборки.

Вместо того, чтобы запускать docker-compose, вы можете реализовать скрипт, который создает изображение с определенным тегом. docker build ... -t your_tag, затем запускает docker-compose. В детских файлах dockerfiles вы можете использовать FROM your_tag.

Незначительное дополнение к Канедиасу.. Если вы решите следовать его подходу (который был моим выбором), вы можете избежать создания экземпляра контейнера для базового образа с помощью--scale флаг из docker-compose up команда:

docker-compose up --scale wls-admin=0

От upкомандная документация:

    --scale SERVICE=NUM        Scale SERVICE to NUM instances. Overrides the
                               `scale` setting in the Compose file if present.

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

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

Вы можете использовать эти dockerfiles в вашем файле compose следующим образом:

version: '3'
services:

  api_cntr:
    image: api_img
    build:
      context: ./api
    container_name:api_cntr
    ports:
      - 5000:5000

Здесь я предположил, что ваш docker-compose.yml файл находится в папке, которая также содержит каталог с именем base-image, А также base-image имеет dockerfile который используется для построения изображения.

Это может быть структура одного из ваших сервисов. Таким же образом вы можете создавать и другие сервисы. И пока ус docker-compose вам не нужно указывать сеть для каждого, потому что все сервисы, объявленные в docker-compose.yml файлы являются частью изолированной сети.

Другие вопросы по тегам