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

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

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

Ответ 1

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

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

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

Пример файла 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}

Пример файла 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

Ответ 2

Решение DOCKER:

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

Последний Docker 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

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

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

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

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

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

Решение BASH:

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

Пример файла .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

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

#!/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 (т.е. ${SECRET_KEY}, чтобы вставить SECRET_KEY из файла .env).

Обратите внимание, что COMPOSE_CONFIG определен в моем файле .env и используется в моем BASH script, но вы можете просто просто заменить {$COMPOSE_CONFIG} на my-compose-file.yml в BASH script.

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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"

Ответ 5

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

Я закончил реализацию "генерации .yml как части CI", как это было предложено @Thomas.

Ответ 6

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

Вот как выглядит мой docker-compose.yml:

services:
  web:
    env_file: variables.env

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

Ответ 7

добавить env в файл .env

Например,

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