Как использовать переменные среды в docker compose


Я хотел бы иметь возможность использовать переменные env внутри docker-compose.yml, со значениями, переданными во время docker-compose up. Вот такой пример. Я делаю это сегодня с помощью команды basic docker run, которая обернута вокруг моего собственного сценария. Есть ли способ достичь этого с помощью compose, без каких-либо таких оберток bash?

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

9 ответов:

  1. создать template.yml, который является вашим docker-compose.yml с переменной окружения.
  2. предположим, что переменные среды находятся в файле 'env.sh'
  3. поместите приведенный ниже фрагмент кода в sh-файл и запустите его.

источник env.sh; rm-rf docker-compose.в формате YML; envsubst " docker-compose.yml";

новый файл docker-compose.yml будет сгенерировано с правильными значениями окружения переменная.

шаблон-образец.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}

образец 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

настройки решение:

похоже, что docker-compose 1.5 + включил подстановку переменных:https://github.com/docker/compose/releases

последний Docker Compose позволяет получить доступ к переменным среды из вашего файла compose. Таким образом, вы можете создать свои переменные среды, а затем запустить Compose следующим образом:

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

затем вы можете ссылаться на переменные в docker-compose.yml с использованием ${VARIABLE}, например Итак:

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

и вот еще информация из документов, взятых здесь:https://docs.docker.com/compose/compose-file/#variable-substitution

когда вы запускаете docker-compose с этой конфигурацией, Compose выглядит для POSTGRES_VERSION переменной окружения в командной строке и подставляет свое значение В. Например, сочинить устраняет изображения для postgres: 9.3 перед запуском конфигурации.

если переменная окружения не задана, составьте заменители с помощью пустая строка. В приведенном выше примере, если POSTGRES_VERSION не установлен, значение параметра image-postgres:.

поддерживаются синтаксис $VARIABLE и ${VARIABLE}. Расширенный функции в стиле оболочки, такие как ${переменная-по умолчанию} и ${VARIABLE/foo / bar}, не поддерживаются.

если нужно поставить знак доллара в значение конфигурации, использованию двойной знак доллара ($$).

и я считаю, что эта функция была добавлена в этот запрос pull: https://github.com/docker/compose/pull/1765

решение Баш:

я замечаю, что у людей есть проблемы с поддержкой переменных окружения Docker. Вместо того, чтобы иметь дело с переменными окружения в Docker, давайте вернемся к основам, таким как bash! Вот более гибкий метод с использованием скрипта bash и .

пример .ОКР файл:

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

затем запустите этот скрипт bash в том же каталоге, который должен развернуть все правильно:

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

просто ссылайтесь на свои переменные env в своем файле compose с обычным синтаксисом bash (ie ${SECRET_KEY} вставить SECRET_KEY С .env file).

Примечание COMPOSE_CONFIG определяется в моем .env файл и используется в моем скрипте bash, но вы можете легко просто заменить {$COMPOSE_CONFIG} С my-compose-file.yml в скрипте bash.

также обратите внимание, что я обозначил это развертывание, назвав все мои контейнеры префиксом "myproject". Вы можете использовать любое имя, но оно помогает идентифицировать ваши контейнеры, чтобы вы могли легко ссылаться на них позже. Предполагая, что ваши контейнеры не имеют состояния, как и должно быть, этот скрипт быстро удалит и повторно развернет ваши контейнеры в соответствии с вашим .env file params и ваш compose YAML файл.

обновление Поскольку этот ответ кажется довольно популярным, я написал сообщение в блоге это описывает мой рабочий процесс развертывания Docker более подробно:http://lukeswart.net/2016/03/lets-deploy-part-1/ это может быть полезно, когда вы добавляете больше сложности в конфигурацию развертывания, такую как конфигурации nginx, сертификаты LetsEncrypt и связанные контейнеры.

при использовании переменных среды для томов вам нужно:

  1. создать .env в той же папке, которая содержит docker-compose.yaml file

  2. объявить переменную в .env file:

    HOSTNAME=your_hostname
    
  3. изменить $hostname до ${HOSTNAME} at docker-compose.yaml file

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

конечно, вы можете сделать это динамически на каждой сборке, как:

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

похоже, что docker-compose теперь имеет встроенную поддержку переменные среды по умолчанию в файле.

все, что вам нужно сделать, это объявить ваши переменные в файле с именем .env и они будут доступны в docker-compose.в формате YML.

например,.env файл с содержимым:

MY_SECRET_KEY=SOME_SECRET
IMAGE_NAME=docker_image

вы можете получить доступ к переменной внутри docker-compose.yml или переслать их в контейнер:

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

вы не можете ... еще. Но это альтернатива, думайте как докер-композитор.генератор yml:

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

в основном сценарий оболочки, который заменит ваши переменные. Также вы можете использовать Grunt task для создания файла docker compose в конце вашего процесса CI.

у меня есть простой скрипт bash, который я создал для этого, это просто означает, что он запускается в вашем файле перед использованием: https://github.com/antonosmond/subber

в основном просто создайте свой файл compose, используя двойные фигурные скобки для обозначения переменных среды, например:

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

все, что в двойных фигурных скобках, будет заменено переменной окружения с тем же именем, поэтому, если бы у меня были следующие переменные окружения:

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

бежать subber docker-compose.yml результирующий файл будет выглядеть так:

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

лучший способ-указать переменные среды вне . Вы можете использовать env_file настройка и определение файла среды в той же строке. Затем выполнение docker-compose up снова должно воссоздать контейнеры с новыми переменными среды.

вот как мой докер-сочинять.yml выглядит так:

services:
  web:
    env_file: variables.env

Примечание.: docker-compose ожидает, что каждая строка в файле env будет находиться в . Избегайте использования export внутри . Кроме того,.env файл должен быть помещен в папку, где выполняется команда docker-compose.

насколько я знаю, это незавершенное производство. Они хотят это сделать, но это еще не выпущено. Смотрите 1377 ("новый" 495 это было упомянуто @Andy).

Я в конечном итоге реализации "создать .yml как часть CI " подход, предложенный @Thomas.

добавить env to .env file

например

VERSION=1.0.0

затем сохраните его в 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