В чем разница между инструкциями ARG и ENV в Dockerfile?

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

Ответ

ARG и ENV — это инструкции для работы с переменными в Dockerfile, но их области видимости и назначение принципиально разные.

Аспект ARG (Аргумент сборки) ENV (Переменная окружения)
Время жизни Только на этапе сборки образа (docker build). Доступны как при сборке, так и в запущенном контейнере (docker run).
Сохраняемость Не сохраняются в итоговом образе. Сохраняются в слое образа и наследуются всеми контейнерами.
Переопределение Через флаг --build-arg в docker build. Через флаг -e в docker run или в Dockerfile.
Основное назначение Параметризация сборки (версии, URL для загрузки). Конфигурация среды выполнения приложения.

Практический пример Dockerfile:

# 1. ARG для динамической версии базового образа (только для сборки)
ARG NGINX_VERSION=alpine
FROM nginx:${NGINX_VERSION}

# 2. ENV для настройки приложения (доступно в контейнере)
ENV APP_ENV=production 
    LOG_LEVEL=info

# ARG можно использовать для передачи секретов на этапе сборки,
# но они не останутся в финальном образе.
ARG BUILD_SECRET
RUN echo "Секрет использован для сборки: $BUILD_SECRET"

# К этому моменту $BUILD_SECRET уже недоступен
CMD ["nginx", "-g", "daemon off;"]

Сборка и запуск:

# Передача ARG и ENV (ENV также можно переопределить при запуске)
docker build --build-arg NGINX_VERSION=1.21-alpine --build-arg BUILD_SECRET=xyz -t myapp .
docker run -e APP_ENV=staging -e LOG_LEVEL=debug myapp

В DevOps ARG часто используют в CI/CD пайплайнах для передачи номеров сборки или веток git, а ENV — для настройки поведения приложения в разных средах (dev, staging, prod).