Production практики для Java в Docker
Управление сборкой и архитектурой
Build args (ARG vs ENV): передача параметров при сборке
- ARG — переменная, доступная только на этапе сборки образа. Не сохраняется в финальном образе.
- ENV — переменная, доступная во время выполнения контейнера. Сохраняется в образе.
Как это работает:
- При выполнении docker build --build-arg JAVA_VERSION=17 . значение JAVA_VERSION передается в Dockerfile через ARG.
- Если ARG используется в ENV, его значение копируется в образ:
Нюансы безопасности:
- Никогда не передавайте секреты через ARG без флага --secret (например, токены для приватных репозиториев):
В Dockerfile:
- Почему это важно: Секреты, переданные через ARG, попадают в историю образа (видны в docker history).
Пример для Maven:
- MAVEN_VERSION используется только при загрузке Maven и не сохраняется в образе.
Multi-arch образы (ARM64 vs x86) и кросс-сборка
Образы, собранные для разных архитектур процессоров (x86_64, ARM64), чтобы запускаться на любом устройстве — от серверов до Raspberry Pi.
Как это работает:
- Docker использует QEMU для эмуляции архитектур через binfmt_misc (механизм ядра Linux).
- Buildx — расширение Docker CLI для кросс-платформенной сборки:
- При пушинге в реестр создается manifest list — файл, описывающий образы для разных архитектур.
Нюансы:
- Эмуляция через QEMU:
- Требует установки qemu-user-static:
- Замедляет сборку на 20-30% из-за эмуляции.
- Сборка нативно:
- Для ARM64 используйте серверы с ARM-процессорами (AWS Graviton, Raspberry Pi).
- В CI/CD настройте параллельную сборку для каждой архитектуры.
Пример для Java:
- Переменная TARGETARCH автоматически устанавливается Buildx (значения: amd64, arm64).
Использование .dockerignore для ускорения сборки
Файл, исключающий ненужные директории/файлы из build context — набора данных, передаваемых Docker Daemon при сборке.
Почему это критично:
- Build context отправляется в память Docker Daemon через сокет.
- Если в контексте есть target/ (500 МБ), сборка замедлится из-за передачи данных.
Типичное содержимое .dockerignore:
Как это работает:
1. При docker build . CLI сканирует текущую директорию.
2. Файлы из .dockerignore исключаются из контекста.
3. Оставшиеся данные архивируются и отправляются в память Docker Daemon (через /var/run/docker.sock).
Нюанс:
- .dockerignore не влияет на COPY в Dockerfile. Если файл исключен из контекста, COPY завершится ошибкой.
#Java #middle #Docker #Production
Управление сборкой и архитектурой
Build args (ARG vs ENV): передача параметров при сборке
- ARG — переменная, доступная только на этапе сборки образа. Не сохраняется в финальном образе.
- ENV — переменная, доступная во время выполнения контейнера. Сохраняется в образе.
Как это работает:
- При выполнении docker build --build-arg JAVA_VERSION=17 . значение JAVA_VERSION передается в Dockerfile через ARG.
- Если ARG используется в ENV, его значение копируется в образ:
ARG JAVA_VERSION=17
ENV JAVA_VERSION=${JAVA_VERSION}
Здесь JAVA_VERSION станет частью образа и будет доступна в runtime.
Нюансы безопасности:
- Никогда не передавайте секреты через ARG без флага --secret (например, токены для приватных репозиториев):
docker build --secret id=github,src=./github.token .
В Dockerfile:
RUN --mount=type=secret,id=github \
git clone https://$(cat /run/secrets/github)@github.com/private/repo.git
- Почему это важно: Секреты, переданные через ARG, попадают в историю образа (видны в docker history).
Пример для Maven:
ARG MAVEN_VERSION=3.8.6
ARG USER_HOME_DIR="/root"
RUN mkdir -p /usr/share/maven && \
curl -fsSL "https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz" \
| tar -xzC /usr/share/maven --strip-components=1
- MAVEN_VERSION используется только при загрузке Maven и не сохраняется в образе.
Multi-arch образы (ARM64 vs x86) и кросс-сборка
Образы, собранные для разных архитектур процессоров (x86_64, ARM64), чтобы запускаться на любом устройстве — от серверов до Raspberry Pi.
Как это работает:
- Docker использует QEMU для эмуляции архитектур через binfmt_misc (механизм ядра Linux).
- Buildx — расширение Docker CLI для кросс-платформенной сборки:
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
- При пушинге в реестр создается manifest list — файл, описывающий образы для разных архитектур.
Нюансы:
- Эмуляция через QEMU:
- Требует установки qemu-user-static:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- Замедляет сборку на 20-30% из-за эмуляции.
- Сборка нативно:
- Для ARM64 используйте серверы с ARM-процессорами (AWS Graviton, Raspberry Pi).
- В CI/CD настройте параллельную сборку для каждой архитектуры.
Пример для Java:
# Сборка под ARM64 и x86_64
FROM --platform=$BUILDPLATFORM openjdk:17 AS builder
ARG TARGETARCH
RUN echo "Собираем под архитектуру: ${TARGETARCH}"
COPY . .
RUN ./mvnw package -DskipTests
- Переменная TARGETARCH автоматически устанавливается Buildx (значения: amd64, arm64).
Использование .dockerignore для ускорения сборки
Файл, исключающий ненужные директории/файлы из build context — набора данных, передаваемых Docker Daemon при сборке.
Почему это критично:
- Build context отправляется в память Docker Daemon через сокет.
- Если в контексте есть target/ (500 МБ), сборка замедлится из-за передачи данных.
Типичное содержимое .dockerignore:
.git
.gitignore
**/target/
**/*.log
**/.idea/
**/.vscode/
docker-compose.yml
Как это работает:
1. При docker build . CLI сканирует текущую директорию.
2. Файлы из .dockerignore исключаются из контекста.
3. Оставшиеся данные архивируются и отправляются в память Docker Daemon (через /var/run/docker.sock).
Нюанс:
- .dockerignore не влияет на COPY в Dockerfile. Если файл исключен из контекста, COPY завершится ошибкой.
#Java #middle #Docker #Production
👍4