Как передать переменные внутрь Docker-образа при сборке, чтобы они были доступны во время выполнения контейнера?

«Как передать переменные внутрь Docker-образа при сборке, чтобы они были доступны во время выполнения контейнера?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Чтобы переменные были доступны внутри запущенного контейнера, их нужно определить как переменные окружения (ENV) в Dockerfile. Часто эти значения ENV задаются динамически через аргументы сборки (ARG).

Правильный паттерн: Использовать ARG для приема значения при сборке и ENV для его сохранения в образе.

Пример Dockerfile:

FROM nginx:alpine

# 1. Объявляем аргумент сборки. Может иметь значение по умолчанию.
ARG API_URL="http://default-api.example.com"
ARG APP_VERSION

# 2. Сохраняем аргумент в переменную окружения образа.
#    Теперь она будет доступна как во время сборки, так и при запуске контейнера.
ENV API_URL=${API_URL}
ENV APP_VERSION=${APP_VERSION}
ENV NGINX_ENV=production

# 3. Использование на этапе сборки (опционально).
RUN echo "Building version ${APP_VERSION} for API at ${API_URL}" > /build-info.txt

# 4. Переменные ENV доступны для процессов в контейнере.
#    Например, можно использовать их в шаблонах конфигурации.
COPY nginx.conf.template /etc/nginx/nginx.conf.template
RUN envsubst '${API_URL}' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf

Сборка образа с передачей переменных:

docker build 
  --build-arg APP_VERSION="2.1.0" 
  --build-arg API_URL="https://api.mycompany.com/v2" 
  -t my-frontend:latest .

Проверка переменных в запущенном контейнере:

# Запуск контейнера
docker run -d --name test-app my-frontend:latest

# Проверка переменных окружения внутри контейнера
docker exec test-app env | grep -E "API_URL|APP_VERSION"
# Вывод:
# API_URL=https://api.mycompany.com/v2
# APP_VERSION=2.1.0

Альтернативный способ: динамическая передача при запуске Иногда значение не нужно «зашивать» в образ, а должно задаваться при каждом запуске. Для этого используется флаг -e (или --env):

docker run -e "API_URL=https://staging-api.example.com" my-frontend:latest

Переменная, переданная через -e, переопределит значение ENV, заданное в Dockerfile, для этого конкретного запуска контейнера.

Итог: Для статических конфигураций, общих для всех инстансов (например, версия приложения), используйте ARG + ENV в Dockerfile. Для динамических или секретных данных (пароли, ключи API) — передавайте через -e при docker run или используйте Docker Secrets / Kubernetes ConfigMaps в оркестраторах.