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
?
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.
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 .
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)
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!
% 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)
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 .
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.}\""'