wake-up-neo.com

Verwendung von Umgebungsvariablen in Docker Compose

Ich möchte Env-Variablen in docker-compose.yml verwenden können, wobei die Werte zum Zeitpunkt des docker-compose up .. eingehen. Dies ist das Beispiel. Ich mache das heute mit dem grundlegenden Docker-Run-Befehl, der um mein eigenes Skript herum gehüllt ist. Gibt es eine Möglichkeit, dies mit compose zu erreichen, ohne solche Bash-Wrapper?

proxy:
  hostname: $hostname
  volumes:
    - /mnt/data/logs/$hostname:/logs
    - /mnt/data/$hostname:/data
123
Dmitry z
  1. Erstellen Sie einen template.yml, der Ihr docker-compose.yml mit Umgebungsvariable ist.
  2. Angenommen, Ihre Umgebungsvariablen befinden sich in einer Datei "env.sh".
  3. Fügen Sie den folgenden Code in eine SH-Datei ein und führen Sie ihn aus.

quelle env.sh; rm -rf docker-compose.yml; envsubst <"template.yml"> "docker-compose.yml";

Eine neue Datei docker-compose.yml wird mit den korrekten Werten der Umgebungsvariablen generiert.

Beispiel template.yml Datei:

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}

Beispieldatei 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

Die DOCKER-Lösung:

Offenbar hat docker-compose 1.5+ das Ersetzen von Variablen aktiviert: https://github.com/docker/compose/releases

Mit der neuesten Docker Compose können Sie über Ihre Compose-Datei auf Umgebungsvariablen zugreifen. So können Sie Ihre Umgebungsvariablen beziehen und dann wie folgt Compose ausführen:

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

Dann können Sie die Variablen in docker-compose.yml mit $ {VARIABLE} wie folgt referenzieren:

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

Und hier sind weitere Informationen aus den Dokumenten, die Sie hier finden: https://docs.docker.com/compose/compose-file/#variable-substitution

Wenn Sie mit dieser Konfiguration Docker-Compose ausführen, sieht Compose aus für die Umgebungsvariable POSTGRES_VERSION in der Shell und Ersetzt den Wert in. In diesem Beispiel löst Compose das Bild auf an postgres: 9.3 vor dem Ausführen der Konfiguration.

Wenn keine Umgebungsvariable festgelegt ist, wird Compose durch eine .__ ersetzt. leerer String. Wenn im obigen Beispiel POSTGRES_VERSION nicht gesetzt ist, Der Wert für die Bildoption lautet postgres :.

Sowohl die $ VARIABLE- als auch die $ {VARIABLE} -Syntax werden unterstützt. Verlängert Shell-Style-Funktionen wie $ {VARIABLE-default} und $ {VARIABLE/foo/bar} werden nicht unterstützt.

Wenn Sie ein literales Dollarzeichen in einen Konfigurationswert setzen müssen, verwenden Sie ein doppeltes Dollarzeichen ($$).

Ich glaube, dieses Feature wurde in dieser Pull-Anfrage hinzugefügt: https://github.com/docker/compose/pull/1765

Die BASH-Lösung:

Ich habe festgestellt, dass Leute Probleme mit der Unterstützung der Umgebungsvariablen von Docker haben. Anstatt sich mit Umgebungsvariablen in Docker zu beschäftigen, gehen wir zurück zu den Grundlagen, wie zum Beispiel bash! Hier ist eine flexiblere Methode, die ein Bash-Skript und eine .env-Datei verwendet.

Eine .env-Beispieldatei:

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

führen Sie dann dieses Bash-Skript in demselben Verzeichnis aus, in dem alles ordnungsgemäß bereitgestellt werden muss:

#!/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

Verweisen Sie Ihre env-Variablen in Ihrer Compose-Datei einfach mit der üblichen Bash-Syntax (dh ${SECRET_KEY}, um den SECRET_KEY aus der .env-Datei einzufügen).

Beachten Sie, dass COMPOSE_CONFIG in meiner .env-Datei definiert und in meinem Bash-Skript verwendet wird. Sie können jedoch {$COMPOSE_CONFIG} einfach durch my-compose-file.yml im Bash-Skript ersetzen.

Beachten Sie auch, dass ich diese Bereitstellung gekennzeichnet habe, indem ich alle Container mit dem Präfix "myproject" benannte. Sie können jeden beliebigen Namen verwenden, aber er hilft Ihnen bei der Identifizierung Ihrer Container, damit Sie sie später leicht referenzieren können. Unter der Annahme, dass Ihre Container stateless sind, wie es sein sollte, entfernt dieses Skript Ihre Container entsprechend Ihren .env-Dateiparametern und Ihrer YAML-Datei.

Update Da diese Antwort ziemlich populär erscheint, habe ich einen Blogbeitrag geschrieben, der meinen Docker-Bereitstellungsworkflow ausführlicher beschreibt: http://lukeswart.net/2016/03/lets-deploy-part- 1/ Dies kann hilfreich sein, wenn Sie einer Bereitstellungskonfiguration, wie nginx configs, LetsEncrypt-Zertifikaten und verknüpften Containern, mehr Komplexität verleihen.

182
modulitos

Es scheint, dass Docker-Compose jetzt native Unterstützung für Standard-Umgebungsvariablen in Datei hat.

sie müssen lediglich Ihre Variablen in einer Datei mit dem Namen .env deklarieren, die dann in docker-compose.yml verfügbar ist.

Zum Beispiel für .env-Datei mit Inhalt:

MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image

Sie können auf Ihre Variable in docker-compose.yml zugreifen oder sie in den Container weiterleiten:

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

Wenn Sie Umgebungsvariablen für Datenträger verwenden, benötigen Sie:

  1. erstellen Sie .env file in demselben Ordner, der docker-compose.yaml-Datei enthält

  2. deklarieren Sie die Variable in der .env-Datei:

    HOSTNAME=your_hostname
    
  3. Ändern Sie $hostname in ${HOSTNAME} in der docker-compose.yaml-Datei

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

Natürlich kannst du das dynamisch bei jedem Build machen:

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

Am besten geben Sie Umgebungsvariablen außerhalb der docker-compose.yml-Datei an. Sie können die Einstellung env_file verwenden und Ihre Umgebungsdatei in derselben Zeile definieren. Beim erneuten Erstellen eines Docker-Composes sollten die Container mit den neuen Umgebungsvariablen neu erstellt werden.

So sieht mein docker-compose.yml aus:

services:
  web:
    env_file: variables.env

Hinweis: docker-compose erwartet, dass jede Zeile in einer env-Datei im VAR=VAL-Format vorliegt. Vermeiden Sie die Verwendung von export in der .env-Datei. Die .env-Datei sollte auch in dem Ordner abgelegt werden, in dem der Befehl docker-compose ausgeführt wird.

7
Jibu James

Du kannst noch nicht. Dies ist jedoch eine Alternative, denken Sie wie ein Docker-Composer.yml-Generator:

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

Im Grunde ein Shell-Skript, das Ihre Variablen ersetzt. Sie können auch die Grunt-Task verwenden, um am Ende Ihres CI-Prozesses eine Docker-Compose-Datei zu erstellen.

5
Thomas Decaux

Ich habe ein einfaches Bash-Skript, das ich für dieses Programm erstellt habe. Es bedeutet, dass es vor der Verwendung in Ihrer Datei ausgeführt wird: https://github.com/antonosmond/subber

Grundsätzlich erstellen Sie einfach Ihre Kompositionsdatei mit doppelten geschweiften Klammern, um Umgebungsvariablen zu kennzeichnen, z.

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

Alles in doppelten geschweiften Klammern wird durch die Umgebungsvariable mit demselben Namen ersetzt. Wenn ich also die folgenden Umgebungsvariablen gesetzt habe:

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

beim Ausführen von subber docker-compose.yml würde die resultierende Datei folgendermaßen aussehen:

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

Folgendes gilt für Docker-compose 3.x Umgebungsvariablen innerhalb des Containers festlegen 

methode - 1 Gerade Methode

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

methode - 2 Die ".env" -Datei

Erstellen Sie eine .env-Datei am selben Speicherort wie die Docker-compose.yml

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

und Ihre Kompositionsdatei wird wie sein

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

Quelle

2
Gajendra D Ambi

Soweit ich weiß, handelt es sich hierbei um eine unfertige Arbeit. Sie wollen es tun, aber es ist noch nicht veröffentlicht. Siehe 1377 (das "neue" 495 wurde von @Andy erwähnt).

Am Ende implementierte ich den von @Thomas vorgeschlagenen Ansatz ".yml als Teil von CI".

1
anroots

Verwenden Sie die ENV-Datei, um dynamische Werte in docker-compse.yml zu definieren. Sei es Port oder irgendein anderer Wert.

Beispiel für Docker-Compose:

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}

In der .env-Datei können Sie den Wert dieser Variablen definieren:

CONSUL_IP=172.31.28.151
Host_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002
0
sorabzone

füge env zur .env-Datei hinzu

Sowie

VERSION=1.0.0

dann speichern Sie es in 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