Docker compose'de ortam değişkenleri nasıl kullanılır?


217

Docker-compose sırasında değerleri geçen docker-compose.yml içindeki env değişkenlerini kullanabilmek istiyorum. Bu örnek. Bugün kendi betiğime sarılmış temel docker run komutu ile yapıyorum. Bu tür bash sarıcıları olmadan beste ile elde etmenin bir yolu var mı?

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


2
Oluşturmanın son sürümünde çözüldü, örneğin olduğu gibi çalışacak. değişken değiştirme ile ilgili docs.docker.com/compose/compose-file/#variable-substitution öğesini kontrol edin .
natbusa

1
Docker uygulamasını unutmayın (Haziran 2018'den beri): stackoverflow.com/a/51007138/6309
VonC

Yanıtlar:


93
  1. Ortam değişkeniniz template.ymlolan bir a oluşturun docker-compose.yml.
  2. Ortam değişkenlerinizin 'env.sh' dosyasında olduğunu varsayalım
  3. Aşağıdaki kod parçasını bir sh dosyasına koyun ve çalıştırın.

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

docker-compose.ymlOrtam değişkenlerinin doğru değerleri ile yeni bir dosya oluşturulacaktır.

Örnek template.yml dosyası:

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}

Örnek env.sh dosyası:

#!/bin/bash 
export ORACLE_DB_IMAGE=<image-name> 
export ORACLE_DB_PORT=<port to be exposed> 
export ORACLE_DB_CONTAINER_NAME=ORACLE_DB_SERVER

@Meet Bu yaklaşımı biraz daha ayrıntılı olarak özetlediğim "BASH çözümü" altında yanıtımı kontrol etmekten çekinmeyin.
modulitos

7
şu anda hala daha iyi bir çözüm yok mu?
lvthillo

13
neden bir dosyayı özyinelemeli olarak silebilirsiniz? (rm -rf docker-compose.yml)
moritzschaefer

@ lorenzvth7 Aşağıdaki cevabımı kontrol edebilirsiniz, ki bu biraz daha kapsamlı olduğunu düşünüyorum: stackoverflow.com/a/33186458/1884158
modulitos

5
-1 bu çözüm yalnızca işleri karmaşıklaştırır ve docker-compose yeni yeteneklerine göre güncellenmelidir docs.docker.com/compose/environment-variables/…
Efrat Levitan

240

DOCKER çözümü:

Docker-compose 1.5+, değişkenlerin değiştirilmesini etkinleştirdi gibi görünüyor: https://github.com/docker/compose/releases

En son Docker Compose, oluşturma dosyanızdan ortam değişkenlerine erişmenizi sağlar. Böylece ortam değişkenlerinizi kaynaklayabilir ve ardından Compose komutunu şu şekilde çalıştırabilirsiniz:

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

Daha sonra $ {VARIABLE} kullanarak docker-compose.yml değişkenlerine şu şekilde başvurabilirsiniz:

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

Ve burada alınan dokümanlar hakkında daha fazla bilgi: https://docs.docker.com/compose/compose-file/#variable-substitution

Docker-compose komutunu bu yapılandırmayla çalıştırdığınızda, Compose kabuktaki POSTGRES_VERSION ortam değişkenini arar ve değerini değiştirir. Bu örnekte, Compose, yapılandırmayı çalıştırmadan önce görüntüyü postgres: 9.3 olarak çözümler.

Bir ortam değişkeni ayarlanmamışsa, Compose, boş bir dize ile değiştirir. Yukarıdaki örnekte, POSTGRES_VERSION ayarlanmamışsa, resim seçeneğinin değeri postgres: şeklindedir.

Hem $ VARIABLE hem de $ {VARIABLE} sözdizimi desteklenir. $ {VARIABLE-default} ve $ {VARIABLE / foo / bar} gibi genişletilmiş kabuk stili özellikleri desteklenmez.

Yapılandırma değerine gerçek bir dolar işareti koymanız gerekiyorsa, çift dolar işareti ($$) kullanın.

Ve bu özelliğin bu çekme isteğine eklendiğine inanıyorum: https://github.com/docker/compose/pull/1765

BASH çözümü:

İnsanların Docker'ın ortam değişkenleri desteği ile ilgili sorunları olduğunu fark ettim. Docker'daki ortam değişkenleriyle uğraşmak yerine bash gibi temellere geri dönelim! İşte bir bash betiği ve bir .envdosya kullanan daha esnek bir yöntem .

Örnek bir .env dosyası:

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

daha sonra bu bash betiğini aynı dizinde çalıştırın;

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

Oluşturma dosyanızdaki env değişkenlerinize her zamanki bash sözdizimiyle (yani , dosyadan ${SECRET_KEY}eklemek için ) başvurmanız yeterlidir .SECRET_KEY.env

Not COMPOSE_CONFIGbenim tanımlanan .envdosya ve benim bash komut kullanılır, ancak kolayca sadece yerini alabilir {$COMPOSE_CONFIG}ile my-compose-file.ymlbash komut.

Ayrıca tüm dağıtımlarımı "projem" önekiyle adlandırarak bu dağıtımı etiketlediğimi de unutmayın. İstediğiniz herhangi bir adı kullanabilirsiniz, ancak daha sonra kolayca başvurabilmeniz için kapsayıcılarınızı tanımlamanıza yardımcı olur. Kaplarınızın durumsuz olduğu varsayıldığında, bu komut dosyası kaplarınızı .env dosya parametrelerinize ve oluşturma YAML dosyanıza göre hızla kaldıracak ve yeniden dağıtacaktır.

Güncelleme Bu yanıt oldukça popüler göründüğünden, Docker dağıtım iş akışımı daha derinlemesine açıklayan bir blog yazısı yazdım: http://lukeswart.net/2016/03/lets-deploy-part-1/ Bu, eklediğinizde yardımcı olabilir nginx yapılandırmaları, LetsEncrypt sertifikaları ve bağlantılı kapsayıcılar gibi bir dağıtım yapılandırmasında daha karmaşık.


2
Bunun grep foo file.textyerine basitçe yapabilirsiniz cat file.text | grep foo. Benim durumumda yapmak zorundaydım export $(grep "^[^#]" .config | xargs) && cat docker-compose.yml | envsubst.
Jorge Lavín

"İnsanların Docker'ın ortam değişkenleri desteği ile ilgili sorunları olduğunu fark ettim" - herhangi bir ayrıntı veya bilet bağlantısı var mı?
tleyden

Maalesef yaşadığım belirli bir sorunu kaydetmedim ve çok uzun zaman önceydi (~ 6 ay), hala alakalı olup olmadığını bilmiyorum. Ancak evet, Docker ortam değişkeni desteğindeki bazı özellikler hatalıdır ve birden fazla kullanıcı tarafından bildirilmiştir. Şimdi daha iyi olduğuna inanıyorum. Ancak dağıtım yapılandırması önemli ölçüde karmaşık hale geldiğinde, yapılandırma mantığını işlemek için bash ve konteyner düzenleme için Docker Compose kullanarak bunu modülerleştirmeyi tercih ederim.
modulitos

8
PSA: Bu sadece ile çalışır,docker-compose up ile değil docker-compose run.
Kriegslustig

5
Bu çözüm vardır docs.docker.com/compose/compose-file/#envfile bir ortam değişkenleri eklemek nerede kullandığını .envunder env_file. Sonra docker-compose.ymlkullanarak değişkenlere ${VARIABLE}
başvurabilirsiniz

112

Docker-compose'un dosyadaki varsayılan ortam değişkenleri için artık yerel desteği var gibi görünüyor .

tek yapmanız gereken değişkenlerinizi adlandırılmış bir dosyada bildirmektir .envve bunlar docker-compose.yml dosyasında bulunur.

Örneğin, .enviçeriğe sahip dosya için :

MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image

Değişkeninize erişebilir docker-compose.ymlveya bunları kabın içine iletebilirsiniz:

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

4
bu en iyi çözüm!
Ladenkov Vladislav

4
Bu benim için de işe yaradı. Neden bilmiyorum ama dosya adı tam anlamıyla olmalı .env, örneğin config.envbenim için çalışmadı.
HBat

1
@ "". gizli bir dosya anlamına gelir - bu, yerel yapılandırma dosyaları için olağan prosedürdür
Jeremy Hajek

2
En iyi çözüm. ve / etc / çevre desteği ekleyebilir ve bunları .env kullanarak bir ortam olarak kullanabiliriz. Bu daha güvenli olacak.
Chinthaka Dinadasa

24

Aşağıdakiler docker-compose 3.x için geçerlidir Kapsayıcı içindeki ortam değişkenlerini ayarlama

yöntem - 1 Düz yöntem

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

method - 2 “.env” dosyası

Docker-compose.yml ile aynı konumda bir .env dosyası oluşturun

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

ve oluşturma dosyanız şöyle olacak

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

kaynak


2
Yöntem 1'in tam bir örneğini görmek istiyorum. Bu işi yapamadım, yani .env dosyasını (ki bu iyi çalıştı) kullanarak sona erdi.
BobHy

20

İhtiyaç duyduğunuz birimler için ortam değişkenlerini kullanırken:

  1. oluşturmak .env içeren aynı klasöre docker-compose.yaml dosya

  2. .envdosyada değişken bildir :

    HOSTNAME=your_hostname
    
  3. Değişim $hostnameiçin ${HOSTNAME}de docker-compose.yaml dosyaya

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

Elbette bunu her yapıda dinamik olarak yapabilirsiniz:

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

9
Not, belgelere göre:The .env file feature only works when you use the docker-compose up command and does not work with docker stack deploy.
James Gentes

19

En iyi yol, docker-compose.ymldosyanın dışındaki ortam değişkenlerini belirtmektir . env_fileAyarı kullanabilir ve ortam dosyanızı aynı satırda tanımlayabilirsiniz. Daha sonra bir liman işçiliği oluşturma işlemi, yeni ortam değişkenleriyle kapları yeniden oluşturmalıdır.

Benim docker-compose.yml şöyle görünüyor:

services:
  web:
    env_file: variables.env

Not: docker-compose, bir env dosyasındaki her satırın VAR=VALformatta olmasını bekler . Dosyanın exportiçinde kullanmaktan kaçının .env. Ayrıca, .envdosya docker-compose komutunun yürütüldüğü klasöre yerleştirilmelidir.


2
Gerçekten en iyi yol
Dany

HAYIR. Ortam değişkenlerini docker kapsayıcısının içinde otomatik olarak kullanılabilir hale getirmez. Yine de bunları çevre bölümü altında açıkça belirtmeniz gerekiyor.
kta

6

Yapamazsın ... henüz. Ancak bu bir alternatiftir, bir docker-composer.yml jeneratörü gibi düşünün:

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

Temel olarak değişkenlerinizin yerini alacak bir kabuk betiği. Ayrıca Cunt işleminizin sonunda docker oluşturma dosyanızı oluşturmak için Grunt görevini kullanabilirsiniz.


4

Bunun için oluşturduğum basit bir bash betiğim var, sadece kullanmadan önce dosyanızda çalıştırmak anlamına gelir: https://github.com/antonosmond/subber

Temel olarak, oluşturma değişkeninizi ortam değişkenlerini belirtmek için çift kıvırcık parantez kullanarak oluşturun:

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

Aşağıdaki kıvırcık değişkenleri ayarlamış olsaydım, çift kıvırcık parantez içindeki herhangi bir şey aynı addaki ortam değişkeniyle değiştirilecektir:

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

subber docker-compose.ymlortaya çıkan dosyayı çalıştırırken şöyle görünecektir:

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

2

Bildiğim kadarıyla, bu devam eden bir çalışma. Bunu yapmak istiyorlar, ama henüz yayınlanmadı. Bkz 1377 ( "yeni" 495 @Andy olarak bahsedildi).

@Thomas tarafından önerilen "CI'nin bir parçası olarak .yml oluştur" yaklaşımını uyguladım.


1

.env dosyasına env ekle

Gibi

VERSION=1.0.0

sonra şuraya kaydet 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
    

1

Docker-compse.yml dosyasında dinamik değerler tanımlamak için .env dosyasını kullanın. Port ya da başka bir değer olsun.

Örnek liman işçisi oluştur:

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}

.Env dosyasının içinde bu değişkenlerin değerini tanımlayabilirsiniz:

CONSUL_IP=172.31.28.151
HOST_ADDRESS=172.31.16.221
TEST_CORE_PORT=10002

1
env SOME_VAR="I am some var" OTHER_VAR="I am other var" docker stack deploy -c docker-compose.yml

3.6 sürümünü kullanın:

version: "3.6"
services:
  one:
    image: "nginx:alpine"
    environment:
      foo: "bar"
      SOME_VAR:
      baz: "${OTHER_VAR}"
    labels:
      some-label: "$SOME_VAR"
  two:
    image: "nginx:alpine"
    environment:
      hello: "world"
      world: "${SOME_VAR}"
    labels:
      some-label: "$OTHER_VAR"

Bu bağlantıyı aldım https://github.com/docker/cli/issues/939


1

1.25.4 sürümünden bu yana, docker-compose --env-filedeğişken içeren bir dosya belirtmenizi sağlayan seçeneği destekler .

Seninki şöyle görünmeli:

hostname=my-host-name

Ve komut:

docker-compose --env-file /path/to/my-env-file config
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.