Как передать динамический параметр из CI/CD пайплайна в Docker при сборке образа?

«Как передать динамический параметр из CI/CD пайплайна в Docker при сборке образа?» — вопрос из категории DevOps, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для передачи динамических параметров из CI/CD в Docker используется механизм ARG (аргументов сборки).

1. Объявление аргумента в Dockerfile:

# Объявляем аргумент сборки
ARG APP_VERSION
ARG BUILD_ENV

# Используем его для установки переменной окружения
ENV APP_VERSION=${APP_VERSION}
ENV NODE_ENV=${BUILD_ENV}

# Или непосредственно в инструкциях
RUN echo "Building version ${APP_VERSION} for ${BUILD_ENV}"

2. Передача аргументов из CI/CD:

В GitLab CI (.gitlab-ci.yml):

build_image:
  script:
    - docker build 
      --build-arg APP_VERSION="$CI_COMMIT_TAG"
      --build-arg BUILD_ENV="$CI_ENVIRONMENT_SLUG"
      -t my-app:$CI_COMMIT_SHA .

В GitHub Actions:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Build Docker image
        run: |
          docker build 
            --build-arg VERSION=${{ github.sha }} 
            --build-arg COMMIT_DATE="$(date -u)" 
            -t my-app:${{ github.sha }} .

3. Важные ограничения и best practices:

  • Жизненный цикл: Значения ARG доступны только на этапе docker build. Чтобы они были доступны в запущенном контейнере, их нужно явно скопировать в ENV.
  • Безопасность: Не используйте --build-arg для передачи секретов (паролей, токенов). Для этого предназначены docker build --secret (Docker BuildKit) или multi-stage сборка с временными файлами.
  • Кэширование: Изменение значения ARG инвалидирует кэш Docker для всех последующих инструкций.

Пример с условной логикой в Dockerfile:

ARG TARGET_ENV=development

# Устанавливаем разные пакеты в зависимости от окружения
RUN if [ "$TARGET_ENV" = "production" ]; then 
    apt-get install -y --no-install-recommends production-packages; 
    else 
    apt-get install -y development-tools; 
    fi