Поиск по сайту:

Как передать переменные среды в контейнеры Docker


Программы часто контролируют работу с помощью конфигурации, связанной с программным обеспечением, а переменные среды позволяют пользователям устанавливать их во время выполнения. Однако запуск процессов в контейнерах Docker усложняет ситуацию, так как же передать переменные среды в контейнер?

Для чего используются переменные среды?

Переменные среды позволяют отделить конфигурацию от исполняемого файла приложения. Например, вы не хотели бы хранить пароль вашей производственной базы данных в своей кодовой базе — если бы вы это сделали, он был бы виден из Git, и любой, у кого есть доступ к вашему коду, мог бы удалить вашу базу данных.

Вместо этого вы устанавливаете его с помощью переменной среды, которая хранит простую пару ключ-значение и позволяет вам получить доступ к значению в любом приложении, работающем в том же сеансе оболочки (они не доступны глобально). Это также имеет то преимущество, что позволяет легко определять различные конфигурации для разных сред. Например, иметь отдельные ключи для базы данных разработки и рабочей базы данных или использовать другую конечную точку API.

Задать эти переменные для контейнеров Docker можно тремя основными способами: с помощью аргументов CLI, файлов конфигурации .env или с помощью docker-compose.

С аргументом командной строки

Команда docker run, используемая для запуска контейнеров Docker, принимает переменные ENV в качестве аргументов. Просто запустите его с флагом -e, сокращением для --env, и передайте пару ключ=значение:

sudo docker run 
-e POSTGRES_USER='postgres' 
-e POSTGRES_PASSWORD='password' 
...

И, если у вас уже есть эти переменные среды, установленные в среде, в которой выполняется эта команда, вы можете просто передать их напрямую по имени:

// set variable
POSTGRES_PASSWORD='password'

// use it later
docker run -e POSTGRES_PASSWORD -e POSTGRES_USER ...

Дополнительная безопасность с файлом .env

Передача переменных с аргументами CLI прекрасно работает, но у нее есть обратная сторона — эти переменные видны с хоста. Они регистрируются в истории команд и отображаются в списке запущенных процессов.

В Linux есть встроенный способ управления разрешениями для этого — доступ к файлам. Хранение переменных в файле .env позволяет вам контролировать доступ к этому файлу с разрешениями файла (chmod, chown).

Создайте файл .env с переменными в следующем формате, каждая в новой строке:

POSTGRES_PASSWORD='password'
POSTGRES_USER='postgres'
APPLICATION_URL='example.com'

Затем передайте его в docker run с флагом --env-file:

docker run --env-file ./envfile ...

С Docker-Compose

Конечно, многие люди не запускают контейнеры Docker напрямую с помощью docker run, а вместо этого предпочитают использовать файл docker-compose для обработки конфигурации нескольких контейнеров, представляющих один приложение.

Чтобы передать переменные среды в контейнер, запущенный таким образом, вам нужно будет настроить файл компоновки для передачи переменных сеанса в контейнер Docker. Эта конфигурация передает переменную POSTGRES_USER как в среду сборки, так и в среду выполнения, а также устанавливает значение по умолчанию, если оно не существует.

version: '3.1'
services:
  my-service: 
    build:
      context: .
      args:
        - POSTGRES_USER=${POSTGRES_USER:-default}
    environment: 
      - POSTGRES_USER=${POSTGRES_USER:-default}

Вам нужно будет установить переменные среды перед запуском docker-compose up, иначе он не сможет получить к ним доступ. Вы можете сохранить их в файле компоновки, но это обычно отслеживается и контролируется версиями, что противоречит цели переменных env.

С Kubernetes

Kubernetes — это система оркестрации, которая может работать с сотнями контейнеров в сети. Он по-прежнему использует Docker, но вы будете касаться только конфигурации, поэтому передача переменных среды напрямую не сработает.

Вместо этого вы можете определить их в конфигурации пода:

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
    - ...
      env:
        - name: SERVICE_PORT
          value: "80"
        - name: SERVICE_IP
          value: "172.17.0.1"

Kubernetes сложен, и существует множество различных способов работы с переменными среды. Чтобы узнать больше, вы можете прочитать их руководства по внедрению данных в поды.