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

Ответ

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

  • ARG (Аргументы сборки):

    • Назначение: Используются для передачи значений во время сборки Docker-образа (docker build).
    • Видимость: Доступны только на этапе сборки, в слоях, следующих за объявлением ARG. После завершения сборки они не сохраняются в финальном Docker-образе.
    • Почему это важно: Это позволяет передавать конфиденциальные данные (например, токены, пароли) на этапе сборки, не включая их в конечный образ, что повышает безопасность и уменьшает размер образа.
    • Передача: Значения передаются с помощью флага --build-arg <имя>=<значение> при вызове docker build.
    • Пример:
      ARG APP_VERSION=1.0.0
      ARG BUILD_DATE
      RUN echo "Building application version ${APP_VERSION} on ${BUILD_DATE}"
      # APP_VERSION и BUILD_DATE не будут доступны в запущенном контейнере
  • ENV (Переменные окружения):

    • Назначение: Определяют переменные окружения, которые будут доступны во время выполнения контейнера (docker run).
    • Видимость: Доступны во всех последующих слоях Dockerfile после объявления и в запущенном контейнере. Они сохраняются в финальном Docker-образе.
    • Почему это важно: Позволяет конфигурировать приложение внутри контейнера без пересборки образа, например, для разных сред (dev, staging, prod) или для настройки поведения приложения.
    • Передача/Переопределение: Могут быть переопределены при запуске контейнера с помощью флага -e <имя>=<значение>.
    • Пример:
      ENV DB_HOST=localhost
      ENV DB_PORT=5432
      CMD ["sh", "-c", "echo "Connecting to ${DB_HOST}:${DB_PORT}" && python app.py"]
      # DB_HOST и DB_PORT будут доступны в контейнере

Ключевое отличие:

  • ARG — для сборки образа, не сохраняется в нём. Используется для параметризации процесса сборки.
  • ENV — для выполнения контейнера, сохраняется в образе. Используется для настройки поведения приложения внутри контейнера.