← Назад к вопросам

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

2.0 Middle🔥 141 комментариев
#CI/CD и автоматизация#Docker и контейнеризация

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Передача динамических параметров в Docker при сборке

Есть несколько способов передать параметры из CI в Docker образ. Выбор зависит от типа параметра (build-time или run-time).

1. ARG — параметры во время сборки (Build Arguments)

Использование ARG для параметров, которые нужны только при сборке:

FROM python:3.9-slim

# Объявляем ARG
ARG BUILD_DATE
ARG VERSION
ARG COMMIT_SHA

# Используем в Dockerfile
RUN echo "Built on ${BUILD_DATE}"
RUN echo "Version: ${VERSION}"

COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt

CMD ["python", "app.py"]

Передача ARG из CI (GitHub Actions):

name: Build and Push Docker Image

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      
      - name: Build Docker image
        run: |
          docker build \
            --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
            --build-arg VERSION=1.2.3 \
            --build-arg COMMIT_SHA=${{ github.sha }} \
            -t myapp:latest \
            .

Передача ARG из CI (GitLab CI):

build:
  stage: build
  image: docker:20.10.16
  variables:
    DOCKER_DRIVER: overlay2
  script:
    - docker build \
        --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
        --build-arg VERSION=${CI_COMMIT_TAG} \
        --build-arg COMMIT_SHA=${CI_COMMIT_SHA} \
        -t myapp:${CI_COMMIT_TAG} \
        .

Передача ARG из CI (Jenkins):

pipeline {
    agent any
    
    stages {
        stage('Build Docker Image') {
            steps {
                script {
                    sh '''
                        docker build \\
                          --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \\
                          --build-arg VERSION=${BUILD_NUMBER} \\
                          --build-arg COMMIT_SHA=${GIT_COMMIT} \\
                          -t myapp:${BUILD_NUMBER} .
                    '''
                }
            }
        }
    }
}

2. ENV — переменные окружения (Environment Variables)

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

FROM python:3.9-slim

# SET default значения (можно переопределить при запуске)
ENV APP_ENV=production
ENV LOG_LEVEL=INFO
ENV DATABASE_URL=postgresql://localhost/mydb

COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt

CMD ["python", "app.py"]

Передача ENV из Docker Compose:

version: '3.9'
services:
  api:
    image: myapp:latest
    environment:
      APP_ENV: production
      LOG_LEVEL: DEBUG
      DATABASE_URL: postgresql://postgres:5432/mydb
      API_KEY: ${API_KEY}  # из .env файла

Передача ENV при запуске контейнера:

docker run \
  -e APP_ENV=production \
  -e LOG_LEVEL=DEBUG \
  -e DATABASE_URL=postgresql://db:5432/mydb \
  myapp:latest

3. ARG + ENV комбинация

Лучший подход: использовать ARG для сборки, ENV для runtime:

FROM python:3.9-slim

# Build-time arguments
ARG VERSION=1.0.0
ARG BUILD_DATE
ARG COMMIT_SHA

# Сохраняем build-time информацию в labels
LABEL version=${VERSION}
LABEL build.date=${BUILD_DATE}
LABEL commit.sha=${COMMIT_SHA}

# Runtime environment variables
ENV APP_VERSION=${VERSION}
ENV PYTHONUNBUFFERED=1
ENV LOG_LEVEL=INFO

COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt

CMD ["python", "app.py"]

4. Передача параметров через Docker secrets (для Swarm/Kubernetes)

Docker Swarm:

version: '3.8'
services:
  api:
    image: myapp:latest
    secrets:
      - db_password
    environment:
      DATABASE_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    external: true
# В CI/CD
echo "super_secret_password" | docker secret create db_password -

Kubernetes:

apiVersion: v1
kind: Secret
metadata:
  name: app-secrets
type: Opaque
stringData:
  DATABASE_PASSWORD: "secret-password"
  API_KEY: "secret-api-key"
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: app
    image: myapp:latest
    envFrom:
    - secretRef:
        name: app-secrets

5. Build Context — передача конфигов в контейнер

Если нужно вложить динамический конфиг в образ:

# В CI/CD скрипте
echo "DATABASE_URL=postgresql://db:5432/mydb" > .env.build
echo "LOG_LEVEL=DEBUG" >> .env.build

docker build \
  --build-arg CONFIG_FILE=.env.build \
  -t myapp:latest \
  .
FROM python:3.9-slim

ARG CONFIG_FILE=.env.default

COPY ${CONFIG_FILE} /app/.env
COPY . /app
WORKDIR /app

RUN pip install -r requirements.txt

CMD ["python", "app.py"]

6. Практический пример: полный CI/CD pipeline

GitHub Actions с передачей параметров:

name: Build and Deploy

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      image-tag: ${{ steps.image.outputs.tag }}
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Generate image tag
        id: image
        run: echo "tag=${{ github.ref_name }}-${{ github.run_number }}" >> $GITHUB_OUTPUT
      
      - name: Login to DockerHub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      
      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: myrepo/myapp:${{ steps.image.outputs.tag }}
          build-args: |
            VERSION=${{ github.ref_name }}
            BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
            COMMIT_SHA=${{ github.sha }}
      
      - name: Deploy to Kubernetes
        run: |
          kubectl set image deployment/myapp \
            myapp=myrepo/myapp:${{ steps.image.outputs.tag }}

Сравнение подходов

СпособКогда использоватьПример
ARGBuild-time параметрыVERSION, COMMIT_SHA, BUILD_DATE
ENVRuntime параметрыDATABASE_URL, LOG_LEVEL, API_KEY
SecretsЧувствительные данныеПароли, API ключи
Config MapsКонфиги в K8sБольшие конфиги, YAML файлы

Best Practices

  1. ARG для версионирования: Сохраняй версию в LABEL для отладки
  2. ENV для конфигурации: Давай возможность переопределить при запуске
  3. Не храни secrets в образе: Передавай через secrets management
  4. Документируй параметры: Используй LABEL для метаданных
  5. Используй multi-stage: Отделяй build-time параметры от runtime