web-dev-qa-db-fra.com

Fichier env différent mais même yml avec Docker Compose?

Je trouve assez courant d'avoir plusieurs environnements (par exemple, test et prod) mais les conteneurs Docker que je souhaite démarrer sont les mêmes dans les deux environnements. La seule différence est la configuration de l'application que je souhaite spécifier à l'aide d'un env-file. Puisque j'ai plusieurs conteneurs et dépendances entre eux, je veux utiliser docker-compose . Mais autant que je sache, je ne peux spécifier qu'un env-file à l'intérieur du fichier docker-compose.yml (voir docs ). Si tel est le cas, je dois alors cloner mon docker-compose.yml d'origine dans deux fichiers différents (un pour le test et l'autre pour le produit) afin de pointer vers des fichiers env différents. Cela signifie que je dois conserver deux fichiers docker-compose.yml au lieu d'un et que, si je modifie quelque chose, je dois mettre à jour les deux fichiers. 

Est-ce vraiment conforme au design? Pourquoi docker-compose ne me permet-il pas de spécifier --env-file quand je fais docker-compose up ou docker-compose run?

23
Johan

Voir la mise à jour n ° 2 ci-dessous. C'est maintenant possible!

C'est une fonctionnalité très demandée de Docker Compose. Malheureusement, la réponse à l'heure actuelle est que vous ne pouvez pas. Je vous recommande de vous abonner à ces problèmes GitHub pour avoir une meilleure idée quand et si cette fonctionnalité est implémentée:

Le numéro 495 est en fait le plus commenté dans leur répertoire de problèmes pour le moment. Vous n'êtes certainement pas le seul à vouloir faire cela.

Mettre à jour:

Le dernier numéro de suivi est disponible sur https://github.com/docker/compose/issues/1377 .

Mise à jour # 2:

Cette fonctionnalité a été fusionnée et est disponible à partir de Docker Compose 1.5.0. Voir https://github.com/docker/compose/blob/129092b7/docs/yml.md#variable-substitution pour plus d'informations sur l'utilisation.

17
Andy Shinn

Il ne s’agit pas d’une inclusion directe à partir de la ligne de commande, mais si vous avez besoin d’une solution de contournement avant la fusion de 1765 (le correctif pour # 1377 ), vous pouvez utiliser le extends directive avec la directive env_file . Pour plus de commodité, les fichiers des exemples simples ci-dessous sont reproduits dans this repository .

Exemple simple stupide

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

Utilisation

% 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)

Exemple encore plus simple

Ce qui précède fonctionne si vous utilisez les fichiers .env. Si vous n’êtes pas si limité, vous pouvez conserver les paramètres de variable d’environnement dans les fichiers "colle" spécifiques à l’environnement .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!

Utilisation

% 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)

Un peu plus compliqué

Pour ce qui en vaut la peine, l'approche décrite dans cette réponse permet d'utiliser différents fichiers .env pour chaque instance plutôt que pour chaque environnement/invocation. (Je ne suis toutefois pas sûr de son utilité dans la pratique.) En d'autres termes, vous pourriez faire quelque chose comme ceci:

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

Vous pouvez commencer à voir que extends est assez puissant, bien plus que ne le permet la fusion # 1765 .

6
posita

Bons exemples clairs, cependant cela ne fonctionnait pas initialement pour moi jusqu'à ce que je mette à jour le base.yml d'appeler le shell ash.

base.yml

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