Подтвердить что ты не робот

Разный env файл, но тот же yml с Docker Compose?

Я считаю довольно распространенным, что у меня есть несколько сред (например, test и prod), но контейнеры Docker, которые я хочу запустить, одинаковы в обеих средах. Единственная разница - это конфигурация приложения, которую я хочу указать с помощью env-file. Поскольку у меня есть несколько контейнеров и зависимости между ними, я хочу использовать docker-compose. Но afaik я могу указать env-file внутри файла docker-compose.yml (см. docs). Если это так, мне нужно клонировать мой оригинальный docker-compose.yml в два разных файла (один для теста и один для prod), чтобы указать на разные файлы env. Это означает, что я должен поддерживать два docker-compose.yml файла вместо одного, и если я вношу какие-либо изменения, мне нужно обновить оба файла.

Это действительно соответствует дизайну? Почему docker-compose не указывать --env-file, когда я делаю docker-compose up или docker-compose run?

4b9b3361

Ответ 1

См. обновление № 2 ниже. Теперь это возможно!

Это очень востребованная функция Docker Compose. К сожалению, ответ на данный момент заключается в том, что вы не можете. Я бы рекомендовал подписаться на эти вопросы GitHub, чтобы лучше понять, когда и если эта функция будет реализована:

Проблема № 495 на самом деле наиболее прокомментирована в их репозитории выпуска на данный момент. Вы определенно не одиноки в этом, чтобы это сделать.

Update:

Последнее отслеживание проблем находится в https://github.com/docker/compose/issues/1377.

Обновление # 2:

Эта функциональность была объединена и доступна с Docker Compose 1.5.0. Для использования информации см. https://github.com/docker/compose/blob/129092b7/docs/yml.md#variable-substitution.

Ответ 2

Это не прямое включение из командной строки, но если вам требуется обход перед слияние # 1765 (исправление для # 1377) делает его выпуском, вы можете использовать extends вместе с директивой env_file. Для удобства файлы из приведенных ниже простых примеров воспроизводятся в этом репозитории.

Глупый простой пример

base.yml

base:
    image: busybox
    command: bash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'

one.env

WHO=Da Schwartz
SHOUTOUT=Get to...

one_glue.yml

one:
    extends:
        file: base.yml
        service: base
    env_file:
        - one.env

two.env

WHO=Da Schwartz
SHOUTOUT=...da choppa!

two_glue.yml

two:
    extends:
        file: base.yml
        service: base
    env_file:
        - two.env

Использование

% for i in base one_glue two_glue ; do docker-compose --file "${i}.yml" up ; done
Recreating dockercomposeextendsenv_base_1...
Attaching to dockercomposeextendsenv_base_1
base_1 | Simon says, "Silence is golden."
dockercomposeextendsenv_base_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Recreating dockercomposeextendsenv_one_1...
Attaching to dockercomposeextendsenv_one_1
one_1 | Da Schwartz says, "Get to..."
dockercomposeextendsenv_one_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Recreating dockercomposeextendsenv_two_1...
Attaching to dockercomposeextendsenv_two_1
two_1 | Da Schwartz says, "...da choppa!"
dockercomposeextendsenv_two_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)

Даже более простой пример

Вышеупомянутое работает, если вы используете файлы .env. Если вы не настолько ограничены, вы можете сохранить параметры переменной среды в файлах "glue" .yml для среды:

red_glue.yml

red:
    extends:
        file: base.yml
        service: base
    environment:
        - WHO=Stallion
        - SHOUTOUT=I am...

blue_glue.yml

blue:
    extends:
        file: base.yml
        service: base
    environment:
        - WHO=Stallion
        - SHOUTOUT=...the law!

Использование

% for i in red_glue blue_glue ; do docker-compose --file "${i}.yml" up ; done
Creating dockercomposeextendsenv_red_1...
Attaching to dockercomposeextendsenv_red_1
red_1 | Stallion says, "I am..."
dockercomposeextendsenv_red_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Creating dockercomposeextendsenv_blue_1...
Attaching to dockercomposeextendsenv_blue_1
blue_1 | Stallion says, "...the law!"
dockercomposeextendsenv_blue_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)

Немного сложнее

Для того, что стоит, подход, описанный в этом ответе, позволяет использовать разные файлы .env для каждого экземпляра, а не для каждого вызова/среды. (Я не уверен, насколько это полезно на практике.) Другими словами, вы можете сделать что-то вроде этого:

testing.yml

# Only instance1 and instance2 are needed for testing

instance1:
    extends:
        file: base.yml
        service: base
    env_file:
        - test.env # environment-specific
        - instance1_test.env # instance-specific

instance2:
    extends:
        file: base.yml
        service: base
    env_file:
        - test.env
        - instance2_test.env

production.yml

# All four instances are used for production

instance1:
    extends:
        file: base.yml
        service: base
    env_file:
        - prod.env # environment-specific
        - instance1_prod.env # instance-specific

instance2:
    extends:
        file: base.yml
        service: base
    env_file:
        - prod.env
        - instance2_prod.env

instance3:
    extends:
        file: base.yml
        service: base
    env_file:
        - prod.env
        - instance3_prod.env

instance4:
    extends:
        file: base.yml
        service: base
    env_file:
        - prod.env
        - instance4_prod.env

Вы можете начать видеть, что extends довольно мощный, гораздо больше, чем позволяет # 1765 merge.

Ответ 3

Хорошие яркие примеры, однако это изначально не работало для меня, пока я не обновил base.yml, чтобы вызвать оболочку пепла.

base.yml

base:
    image: busybox
    command: ash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'