web-dev-qa-db-fra.com

Comment utiliser les variables d'environnement dans la composition de docker

J'aimerais pouvoir utiliser les variables env dans docker-compose.yml, avec les valeurs passées au moment de docker-compose up . Voici l'exemple. Je le fais aujourd'hui avec la commande de base docker run, qui s'articule autour de mon propre script… .. Y a-t-il un moyen de le réaliser avec compose, sans ces bashpps?

proxy:
  hostname: $hostname
  volumes:
    - /mnt/data/logs/$hostname:/logs
    - /mnt/data/$hostname:/data
123
Dmitry z
  1. Créez un template.yml, qui est votre docker-compose.yml avec variable d’environnement.
  2. Supposons que vos variables d'environnement se trouvent dans un fichier 'env.sh'
  3. Mettez 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=<image-name> 
export Oracle_DB_PORT=<port to be exposed> 
export Oracle_DB_CONTAINER_NAME=Oracle_DB_SERVER
68
Saurabh Kumar

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 à partir de votre fichier de composition. Vous pouvez donc source vos variables d’environnement, puis exécuter Compose comme suit:

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

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

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

Et voici plus d’informations sur les documents, prises ici: https://docs.docker.com/compose/compose-file/#variable-substitution

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

Si aucune variable d’environnement n’est définie, Compose se substitue à un chaîne vide. Dans l'exemple ci-dessus, si POSTGRES_VERSION n'est pas défini, La valeur de l'option image est postgres :.

Les syntaxes $ VARIABLE et $ {VARIABLE} sont supportées. Élargi Fonctionnalités de type shell, telles que $ {VARIABLE-default} et $ {VARIABLE/foo/bar}, ne sont pas supportés.

Si vous devez insérer un signe dollar littéral dans une valeur de configuration, utilisez un double signe dollar ($$).

Et je crois que cette fonctionnalité a été ajoutée à cette demande d'extraction: https://github.com/docker/compose/pull/1765

La solution BASH:

Je remarque que les utilisateurs ont des problèmes avec la prise en charge des variables d’environnement de Docker. Au lieu de traiter les variables d'environnement dans Docker, revenons à l'essentiel, 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 exécutez ce script bash dans le même répertoire, ce 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 vous suffit de référencer vos variables env dans votre fichier de composition avec la syntaxe habituelle bash (c'est-à-dire ${SECRET_KEY} pour insérer le SECRET_KEY à partir du fichier .env).

Notez que COMPOSE_CONFIG est défini dans mon fichier .env et utilisé dans mon script bash, mais vous pouvez facilement simplement remplacer {$COMPOSE_CONFIG} par le 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 le nom de votre choix, mais cela facilite l'identification de vos conteneurs afin que vous puissiez facilement les référencer ultérieurement. En supposant que vos conteneurs soient sans état, comme ils devraient l'être, ce script supprimera et redéployera rapidement vos conteneurs en fonction de vos paramètres de fichier .env et de votre fichier YAML de composition.

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

182
modulitos

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

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

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

MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image

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

my-service:
  image: ${IMAGE_NAME}
  environment:
    MY_SECRET_KEY: ${MY_SECRET_KEY}
27
Doody P

Lorsque vous utilisez des variables d'environnement pour des volumes, vous avez besoin des éléments suivants:

  1. create .env fichier dans le même dossier qui contient 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 dynamiquement sur chaque build comme:

echo "HOSTNAME=your_hostname" > .env && Sudo docker-compose up
14
Nerijus Gedrimas

La meilleure méthode consiste à 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, recomposez docker doit recréer les conteneurs avec les nouvelles variables d'environnement.

Voici à quoi ressemble mon fichier 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 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.

7
Jibu James

Vous ne pouvez pas ... encore. Mais c’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 de CI.

5
Thomas Decaux

J'ai créé un script bash simple pour cela. Cela signifie simplement que vous devez l'exécuter sur votre fichier avant utilisation: https://github.com/antonosmond/subber

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

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

Tout ce qui se trouve entre deux accolades 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

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

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

Les éléments suivants s'appliquent à docker-compose 3.x Définissez les variables d'environnement à l'intérieur du conteneur. 

méthode - 1 méthode droite

web:
  environment:
    - DEBUG=1
      POSTGRES_PASSWORD: 'postgres'
      POSTGRES_USER: 'postgres'

méthode - 2 Le fichier “.env”

Créez un fichier .env au même emplacement que le fichier docker-compose.yml

$ cat .env
TAG=v1.5
POSTGRES_PASSWORD: 'postgres'

et votre fichier de composition sera comme

$ cat docker-compose.yml
version: '3'
services:
  web:
    image: "webapp:${TAG}"
    postgres_password: "${POSTGRES_PASSWORD}"

la source

2
Gajendra D Ambi

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 implémenter l'approche "générer .yml dans le cadre de CI" proposée par @Thomas.

1
anroots

Utilisez le fichier .env pour définir les valeurs dynamiques dans docker-compse.yml. Que ce soit le port ou toute autre valeur.

Exemple de menu fixe:

testcore.web:
       image: xxxxxxxxxxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com/testcore:latest
       volumes: 
            - c:/logs:c:/logs
       ports:
            - ${TEST_CORE_PORT}:80
       environment:
            - CONSUL_URL=http://${CONSUL_IP}:8500 
            - Host=${Host_ADDRESS}:${TEST_CORE_PORT}

Dans le fichier .env, vous pouvez définir la valeur de ces variables:

CONSUL_IP=172.31.28.151
Host_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002
0
sorabzone

ajouter env au fichier .env

Tel que

VERSION=1.0.0

puis enregistrez-le dans 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
0
foxundermon