← Назад к вопросам
Как приложение упаковать в Docker-образ
2.3 Middle🔥 201 комментариев
#Docker, Kubernetes и DevOps
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ответ
Упаковка Java приложения в Docker-образ требует создания Dockerfile и определения зависимостей.
1. Базовый Dockerfile для Spring Boot приложения
# Stage 1: Build
FROM maven:3.8.1-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 2: Runtime
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/target/myapp.jar .
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "myapp.jar"]
2. Многоэтапная сборка (Multi-stage build)
# Build stage
FROM maven:3.8.1-openjdk-11 AS build
WORKDIR /build
COPY . .
RUN mvn clean package -DskipTests
# Runtime stage
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=build /build/target/app.jar application.jar
EXPOSE 8080
CMD ["java", "-jar", "application.jar"]
3. Оптимизированный Dockerfile с кешированием слоев
FROM maven:3.8.1-openjdk-11 AS builder
WORKDIR /app
# Копируем только pom.xml для кеширования зависимостей
COPY pom.xml .
RUN mvn dependency:go-offline -B
# Копируем исходный код
COPY src ./src
COPY .mvn ./.mvn
COPY mvnw ./
# Собираем приложение
RUN mvn clean package -DskipTests -q
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/target/app.jar .
# Не запускаем от root
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
4. Dockerfile с переменными окружения
FROM openjdk:11-jre-slim
WORKDIR /app
# Переменные окружения
ENV APP_PORT=8080
ENV JAVA_OPTS="-Xmx512m -Xms256m"
COPY target/myapp.jar .
EXPOSE ${APP_PORT}
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar myapp.jar"]
5. .dockerignore файл
target/
.git/
.gitignore
.mvn/
node_modules/
*.log
.env
.idea/
.vscode/
*.jar.original
mvnw.cmd
README.md
6. Сборка образа
# Базовая сборка
docker build -t myapp:1.0 .
# С тегом и версией
docker build -t myapp:latest -t myapp:1.0.0 .
# С аргументами
docker build --build-arg VERSION=1.0 -t myapp:1.0 .
# С кешированием
docker build --cache-from myapp:latest -t myapp:1.0 .
7. Запуск контейнера
# Базовый запуск
docker run -p 8080:8080 myapp:1.0
# С переменными окружения
docker run -p 8080:8080 -e SPRING_PROFILES_ACTIVE=prod myapp:1.0
# С подключением томов
docker run -p 8080:8080 -v /data:/app/data myapp:1.0
# В фоне
docker run -d -p 8080:8080 --name myapp-container myapp:1.0
8. Docker Compose для локального запуска
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/mydb
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root123
depends_on:
- mysql
networks:
- app-network
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mydb
ports:
- "3306:3306"
networks:
- app-network
networks:
app-network:
driver: bridge
9. Dockerfile с health check
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/app.jar .
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]
10. Gradle приложение
# Build stage
FROM gradle:7.2-jdk11 AS builder
WORKDIR /app
COPY build.gradle settings.gradle ./
COPY src ./src
RUN gradle clean build --no-daemon -x test
# Runtime stage
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/build/libs/app-*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
11. Минимальный образ с Alpine
FROM maven:3.8.1-openjdk-11 AS builder
WORKDIR /app
COPY . .
RUN mvn clean package -DskipTests
FROM openjdk:11-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/app.jar .
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
12. Push образа в реестр
# Тагирование
docker tag myapp:1.0 registry.hub.docker.com/username/myapp:1.0
# Login в реестр
docker login
# Push
docker push registry.hub.docker.com/username/myapp:1.0
# Pull образа
docker pull registry.hub.docker.com/username/myapp:1.0
Лучшие практики
- Используйте многоэтапную сборку (multi-stage build)
- Минимизируйте размер образа (Alpine, slim версии JDK)
- Кешируйте слои - копируйте зависимости перед кодом
- Не запускайте приложение от root
- Добавляйте HEALTHCHECK
- Используйте .dockerignore
- Устанавливайте правильные версии JDK
- Используйте слим образы вместо полных
- Документируйте переменные окружения
- Тестируйте образ локально перед push
Размер образов
- openjdk:11-jre-slim - 189 MB
- openjdk:11-jre-alpine - 95 MB
- openjdk:11 (full) - 644 MB
В своем опыте я создавал Docker образы для микросервисной архитектуры с optimized multi-stage сборкой, размер итогового образа составлял 120 MB.