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

Как приложение упаковать в 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

Лучшие практики

  1. Используйте многоэтапную сборку (multi-stage build)
  2. Минимизируйте размер образа (Alpine, slim версии JDK)
  3. Кешируйте слои - копируйте зависимости перед кодом
  4. Не запускайте приложение от root
  5. Добавляйте HEALTHCHECK
  6. Используйте .dockerignore
  7. Устанавливайте правильные версии JDK
  8. Используйте слим образы вместо полных
  9. Документируйте переменные окружения
  10. Тестируйте образ локально перед push

Размер образов

  • openjdk:11-jre-slim - 189 MB
  • openjdk:11-jre-alpine - 95 MB
  • openjdk:11 (full) - 644 MB

В своем опыте я создавал Docker образы для микросервисной архитектуры с optimized multi-stage сборкой, размер итогового образа составлял 120 MB.