Ответ
Для параметризации сборки Docker-образа используются инструкции ARG (аргументы сборки). Они позволяют динамически менять версии ПО, пути, флаги компиляции и т.д.
Базовый синтаксис:
- Объявление аргумента в Dockerfile:
FROM alpine:3.18 # Объявляем аргумент с значением по умолчанию ARG APP_VERSION="1.0.0" # Аргумент без значения по умолчанию (должен быть передан) ARG BUILD_ENV - Использование аргумента в инструкциях:
RUN echo "Building version ${APP_VERSION} for environment ${BUILD_ENV}" # ARG можно использовать для задания ENV ENV APP_VERSION=${APP_VERSION} - Передача значения при сборке через
--build-arg:docker build --build-arg APP_VERSION=2.5.0 --build-arg BUILD_ENV=production -t myapp:latest .
Практический пример из опыта — сборка Java-приложения:
# Используем ARG для указания версии Maven и JDK
ARG MAVEN_VERSION=3.9.6
ARG JDK_VERSION=17
FROM maven:${MAVEN_VERSION}-eclipse-temurin-${JDK_VERSION} AS builder
WORKDIR /app
COPY pom.xml .
# Скачиваем зависимости (кешируем этот слой)
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
FROM eclipse-temurin:${JDK_VERSION}-jre
ARG JAR_FILE="target/*.jar"
COPY --from=builder /app/${JAR_FILE} /app/app.jar
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
Сборка с кастомными аргументами:
docker build --build-arg JDK_VERSION=21 --build-arg MAVEN_VERSION=3.9.5 -t myapp:jdk21 .
Важные особенности (Scope):
ARGсуществуют только на этапе сборки и не остаются в финальном образе или его истории. Чтобы значение сохранилось в контейнере на время выполнения, его нужно явно присвоить переменнойENV.- Каждый
ARG«живет» только в одном этапе сборки. Если нужно использовать один и тот же аргумент в несколькихFROM(многоступенчатая сборка), его нужно объявить повторно в каждом нужном этапе. - Предопределенные ARG: Docker предоставляет несколько предопределенных
ARG, таких какHTTP_PROXY,VERSIONи др., которые можно использовать без объявления.