Comment utiliser les variables d’environnement dans docker compose

Je voudrais pouvoir utiliser les variables env dans docker-compose.yml, avec les valeurs transmises lors de la composition de docker. C’est l’exemple. Je le fais aujourd’hui avec la commande de base de docker run, qui est entourée de mon propre script. Y a-t-il un moyen d’y parvenir avec composer, sans de tels enveloppes bash?

proxy: hostname: $hostname volumes: - /mnt/data/logs/$hostname:/logs - /mnt/data/$hostname:/data 

  1. Créez un template.yml , qui correspond à votre variable d’environnement docker-compose.yml .
  2. Supposons que vos variables d’environnement soient dans un fichier ‘env.sh’
  3. Placez le morceau de code ci-dessous dans un fichier sh et exécutez-le.

source env.sh; rm -rf docker-compose.yml; envsubst < "template.yml"> “docker-compose.yml”;

Un nouveau fichier docker-compose.yml sera généré avec les valeurs correctes des variables d’environnement.

Exemple de fichier template.yml:

 oracledb: image: ${ORACLE_DB_IMAGE} privileged: true cpuset: "0" ports: - "${ORACLE_DB_PORT}:${ORACLE_DB_PORT}" command: /bin/sh -c "chmod 777 /tmp/start; /tmp/start" container_name: ${ORACLE_DB_CONTAINER_NAME} 

Exemple de fichier env.sh:

 #!/bin/bash export ORACLE_DB_IMAGE= export ORACLE_DB_PORT= export ORACLE_DB_CONTAINER_NAME=ORACLE_DB_SERVER 

La solution DOCKER:

Il semble que docker-compose 1.5+ ait activé la substitution de variables: https://github.com/docker/compose/releases

La dernière version de Docker Compose vous permet d’accéder aux variables d’environnement de votre fichier de composition. Vous pouvez donc rechercher vos variables d’environnement, puis exécuter Compose comme ceci:

 set -a source .my-env docker-compose up -d 

Ensuite, vous pouvez référencer les variables de docker-compose.yml en utilisant $ {VARIABLE}, comme ceci:

 db: image: "postgres:${POSTGRES_VERSION}" 

Et voici plus d’informations des docs, sockets ici: https://docs.docker.com/compose/compose-file/#variable-substitution

Lorsque vous exécutez docker-composition avec cette configuration, Compose recherche la variable d’environnement POSTGRES_VERSION dans le shell et remplace sa valeur. Pour cet exemple, Compose résout l’image en postgres: 9.3 avant d’exécuter la configuration.

Si une variable d’environnement n’est pas définie, Compose remplace par une chaîne vide. Dans l’exemple ci-dessus, si POSTGRES_VERSION n’est pas défini, la valeur de l’option d’image est postgres :.

La syntaxe de $ VARIABLE et de $ {VARIABLE} est prise en charge. Les fonctionnalités étendues de style shell, telles que $ {VARIABLE-default} et $ {VARIABLE / foo / bar}, ne sont pas sockets en charge.

Si vous avez besoin de mettre un signe littéral dans une valeur de configuration, utilisez un signe double dollar ($$).

Et je crois que cette fonctionnalité a été ajoutée dans cette requête: https://github.com/docker/compose/pull/1765

La solution BASH:

Je remarque que les gens ont des problèmes avec la prise en charge des variables d’environnement de Docker. Au lieu de traiter des variables d’environnement dans Docker, revenons aux bases, comme bash! Voici une méthode plus flexible utilisant un script bash et un fichier .env .

Un exemple de fichier .env:

 EXAMPLE_URL=http://example.com # Note that the variable below is commented out and will not be used: # EXAMPLE_URL=http://example2.com SECRET_KEY=ABDFWEDFSADFWWEFSFSDFM # You can even define the compose file in an env variable like so: COMPOSE_CONFIG=my-compose-file.yml # You can define other compose files, and just comment them out # when not needed: # COMPOSE_CONFIG=another-compose-file.yml 

puis lancez ce script bash dans le même répertoire, qui devrait tout déployer correctement:

 #!/bin/bash docker rm -f `docker ps -aq -f name=myproject_*` set -a source .env cat ${COMPOSE_CONFIG} | envsubst | docker-compose -f - -p "myproject" up -d 

Il suffit de référencer vos variables env dans votre fichier de composition avec la syntaxe bash habituelle (c’est- ${SECRET_KEY} dire ${SECRET_KEY} pour insérer le fichier .env fichier .env ).

Notez que COMPOSE_CONFIG est défini dans mon fichier .env et utilisé dans mon script bash, mais vous pouvez facilement remplacer {$COMPOSE_CONFIG} par le {$COMPOSE_CONFIG} my-compose-file.yml dans le script bash.

Notez également que j’ai étiqueté ce déploiement en nommant tous mes conteneurs avec le préfixe “myproject”. Vous pouvez utiliser n’importe quel nom, mais cela vous aidera à identifier vos conteneurs pour pouvoir les consulter plus tard. En supposant que vos conteneurs sont sans état, comme ils le devraient, ce script va rapidement supprimer et redéployer vos conteneurs en fonction de vos parameters de fichier .env et de votre fichier de composition YAML.

Mise à jour Puisque cette réponse semble très populaire, j’ai écrit un article décrivant plus en détail mon stream de travail de déploiement Docker: http://lukeswart.net/2016/03/lets-deploy-part-1/ Cela pourrait être utile lorsque vous ajoutez plus de complexité pour une configuration de déploiement, comme les configurations nginx, les certificates LetsEncrypt et les conteneurs liés.

Lorsque vous utilisez des variables d’environnement pour des volumes, vous devez:

  1. créer un fichier .env dans le même dossier contenant le fichier docker-compose.yaml

  2. déclarer une variable dans le fichier .env :

     HOSTNAME=your_hostname 
  3. Remplacez $hostname par ${HOSTNAME} dans le fichier docker-compose.yaml

     proxy: hostname: ${HOSTNAME} volumes: - /mnt/data/logs/${HOSTNAME}:/logs - /mnt/data/${HOSTNAME}:/data 

Bien sûr, vous pouvez le faire de manière dynamic sur chaque version, par exemple:

 echo "HOSTNAME=your_hostname" > .env && sudo docker-compose up 

Il semble que docker-compose dispose désormais d’un support natif pour les variables d’environnement par défaut dans le fichier .

tout ce que vous devez faire est de déclarer vos variables dans un fichier nommé .env et elles seront disponibles dans docker-compose.yml.

Par exemple, pour .env fichier .env avec un contenu:

 MY_SECRET_KEY=SOME_SECRET IMAGE_NAME=docker_image 

Vous pouvez accéder à votre variable dans docker-compose.yml ou la transférer dans le conteneur:

 my-service: image: ${IMAGE_NAME} environment: MY_SECRET_KEY: ${MY_SECRET_KEY} 

Vous ne pouvez pas encore … Mais ceci est une alternative, pensez comme un générateur docker-composer.yml:

https://gist.github.com/Vad1mo/9ab63f28239515d4dafd

Fondamentalement, un script shell qui remplacera vos variables. Vous pouvez également utiliser la tâche Grunt pour créer votre fichier de composition de docker à la fin de votre processus CI.

J’ai un simple script bash que j’ai créé pour cela, cela signifie simplement l’exécuter sur votre fichier avant de l’utiliser: https://github.com/antonosmond/subber

Fondamentalement, créez simplement votre fichier de composition en utilisant des accolades doubles pour indiquer les variables d’environnement, par exemple:

 app: build: "{{APP_PATH}}" ports: - "{{APP_PORT_MAP}}" 

Tout ce qui existe entre accolades doubles sera remplacé par la variable d’environnement du même nom, donc si j’avais les variables d’environnement suivantes:

 APP_PATH=~/my_app/build APP_PORT_MAP=5000:5000 

sur exécutant subber docker-compose.yml le fichier résultant ressemblerait à:

 app: build: "~/my_app/build" ports: - "5000:5000" 

Le meilleur moyen est de spécifier des variables d’environnement en dehors du fichier docker-compose.yml . Vous pouvez utiliser le paramètre env_file et définir votre fichier d’environnement dans la même ligne. Ensuite, créer à nouveau un menu fixe devrait recréer les conteneurs avec les nouvelles variables d’environnement.

Voici à quoi ressemble mon docker-compose.yml:

 services: web: env_file: variables.env 

Remarque: docker-compose s’attend à ce que chaque ligne d’un fichier env soit au format VAR=VAL . Évitez d’utiliser l’ export dans le fichier .env . De plus, le fichier .env doit être placé dans le dossier où la commande docker-compose est exécutée.

Pour autant que je sache, il s’agit d’un travail en cours. Ils veulent le faire, mais ce n’est pas encore sorti. Voir 1377 (le “nouveau” 495 mentionné par @Andy).

J’ai fini par mettre en œuvre l’approche “generate .yml dans le cadre de CI” proposée par @Thomas.

append env au fichier .env

Tel que

 VERSION=1.0.0 

puis enregistrez-le sur deploy.sh

 INPUTFILE=docker-compose.yml RESULT_NAME=docker-compose.product.yml NAME=test prepare() { local inFile=$(pwd)/$INPUTFILE local outFile=$(pwd)/$RESULT_NAME cp $inFile $outFile while read -r line; do OLD_IFS="$IFS" IFS="=" pair=($line) IFS="$OLD_IFS" sed -i -e "s/\${${pair[0]}}/${pair[1]}/g" $outFile done < .env } deploy() { docker stack deploy -c $outFile $NAME } prepare deploy