docker-compose: использование нескольких Dockerfiles для нескольких сервисов

Я использую docker-compose и хотел бы использовать разные Dockerfiles для разных этапов сборки сервисов. Документы, похоже, предлагают размещать разные файлы Docker в разных каталогах, но я бы хотел, чтобы все они были в одном и том же (и, возможно, различались при использовании следующего соглашения: Dockerfile.postgres, Dockerfile.main...). Это возможно?

Изменить: сценарий, который я имею, содержит этот файл docker-compose:

main:
  build: .
  volumes:
    - .:/code
  environment:
    - DEBUG=true

postgresdb:
  extends:
    file: docker-compose.yml
    service: main
  build: utils/sql/
  ports:
    - "5432"
  environment:
    - DEBUG=true

где postgresdbDockerfile это:

FROM postgres

# http://www.slideshare.net/tarkasteve/developerweek-2015-docker-tutorial
ADD make-db.sh /docker-entrypoint-initdb.d/

и главное это:

FROM python:2.7

RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/

RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ADD . /code/

Это работает прямо сейчас, но я хотел бы расширить postgresdbDockerfile, вызывая скрипт Python, который создает таблицы в базе данных в соответствии с моделями, основанными на SQL Alchemy (скрипт Python будет называться как python manage.py create_tables). Я хотел добавить его в Dockerfile БД, но из-за изоляции контейнеров я не могу использовать там SQL Alchemy, потому что этот образ основан на postgres изображение вместо Python, и оно не содержит sqlalchemy пакет...

Что я могу сделать? Я пытался использовать main служба в postgresdb, но, к сожалению, он не переносит python и его пакеты, поэтому я все еще не могу написать ни один Dockerfile, который создает базу данных Postgres (через скрипт оболочки), а также ее таблицы (через скрипт Python).

4 ответа

Решение

Это невозможно из-за того, как Docker обрабатывает контексты построения.

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

Смотрите: Dockerfile

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

service1:
    build: service1

service2:
    build: service2

Смотрите: docker-compose

Обновить:

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

В качестве альтернативы вы могли бы взглянуть на более скриптовые и управляемые шаблонами решения, такие как shutit (у меня нет опыта, но я слышал о Боге).

FWIW: разделение проблем ftw:)

Вы должны добавить его в раздел сборки. Таким образом, вы можете указать разные альтернативные файлы Docker для каждого сервиса.

services:
  service1:
    build:
        context: .
        args:
            - NODE_ENV=local
        dockerfile: Dockerfile_X
    ports:
        - "8765:8765"

Ты можешь использовать dockerfile аргумент в вашем docker-compose.yml указать альтернативный для конкретной услуги.

Я не знаю, когда он был добавлен, так как обсуждение старое, но вы можете увидеть его в ссылке https://docs.docker.com/compose/compose-file/

Я пробовал вчера, и это работает со мной. Это базовый каталог для моего проекта Dockerfile а также Dockerfile-service3 и в docker-compose.yml:

version: '2'

services:
    service1:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8765:8765"
        # other args skipped for clarity
    service2:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8766:8766"
        # other args skipped for clarity
    service3:
        build:
            context: .
            dockerfile: Dockerfile-service3
            args:
                - NODE_ENV=local
        ports:
            - "8767:8767"
        # other args skipped for clarity
    service4:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8768:8768"
        # other args skipped for clarity

Таким образом, все услуги, кроме service3 будет построен с использованием стандарта Dockerfile а также service3 будет построен с использованием Dockerfile-service3,

Создатель ShutIt здесь. Приятно слышать, что люди слышат хорошие новости об этом.

Если честно, на вашем месте я бы написал собственный Dockerfile и использовал стандартное управление пакетами, такое как apt или yum. Быстрая проверка с изображением Ubuntu и python-pip и python-sqlalchemy доступны бесплатно.

Есть более замысловатые решения, которые могут работать для вас, используя ShutIt, с удовольствием обсудим это в автономном режиме, так как я думаю, что это немного не по теме. ShutIt был написан для такого вида использования, так как я мог видеть, что это будет распространенной проблемой, учитывая ограниченную полезность Dockerfiles вне пространства микросервисов.

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