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

Как сделать образ проекта

1.0 Junior🔥 91 комментариев
#Другое

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

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

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

Как сделать образ проекта

Docker образ (Docker image) — это неизменяемый шаблон приложения, содержащий код, зависимости, переменные окружения и конфигурацию. Это основной способ упаковки и развёртывания Java приложений в современных системах.

1. Основные концепции

Dockerfile — это текстовый файл с инструкциями для построения образа. Docker образ — это готовый к использованию пакет. Docker контейнер — это запущенный экземпляр образа.

2. Простой Dockerfile для Java приложения

# Используем официальный образ Java
FROM openjdk:17-jdk-slim

# Устанавливаем рабочую директорию
WORKDIR /app

# Копируем JAR файл в контейнер
COPY target/myapp-1.0.0.jar app.jar

# Экспонируем порт
EXPOSE 8080

# Запускаем приложение
ENTRYPOINT ["java", "-jar", "app.jar"]

Построение образа:

# Построить образ
docker build -t myapp:1.0.0 .

# Запустить контейнер
docker run -p 8080:8080 myapp:1.0.0

3. Multi-stage Dockerfile (оптимизированный)

Первый stage — построение, второй — запуск. Это уменьшает размер образа.

# Stage 1: Build
FROM openjdk:17-jdk-slim AS builder

WORKDIR /build

# Копируем pom.xml и зависимости
COPY pom.xml .
RUN mvn dependency:go-offline

# Копируем исходный код и собираем
COPY src ./src
RUN mvn clean package -DskipTests

# Stage 2: Runtime
FROM openjdk:17-jre-slim

WORKDIR /app

# Копируем только JAR из builder stage
COPY --from=builder /build/target/myapp-1.0.0.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

4. Оптимизированный Dockerfile с слоями

FROM openjdk:17-jdk-slim

# Установка переменных окружения
ENV JAVA_OPTS="-Xmx512m -Xms256m"
ENV APP_PORT=8080

WORKDIR /app

# Копируем в отдельных слоях для кеширования
COPY pom.xml .
COPY mvn* ./
RUN mvn dependency:go-offline || true

COPY src ./src
RUN mvn clean package -DskipTests

# Финальный слой - меньший размер
FROM openjdk:17-jre-slim

WORKDIR /app

COPY --from=0 /app/target/*.jar app.jar

EXPOSE ${APP_PORT}

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:${APP_PORT}/actuator/health || exit 1

ENTRYPOINT exec java ${JAVA_OPTS} -jar app.jar

5. Spring Boot Dockerfile (best practices)

# Используем spring boot встроенный слой
FROM openjdk:17-jdk-slim as builder
WORKDIR /workspace/app

COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src

# Строим приложение
RUN ./mvnw -B clean package -DskipTests

# Раскладываем JAR для оптимизации
RUN mkdir -p target/dependency && \
    cd target/dependency && \
    jar -xf ../*.jar

# Runtime image
FROM openjdk:17-jre-slim

RUN useradd -m app
USER app

WORKDIR /app

# Копируем слои из builder
COPY --from=builder /workspace/app/target/dependency/BOOT-INF/lib /app/lib
COPY --from=builder /workspace/app/target/dependency/META-INF /app/META-INF
COPY --from=builder /workspace/app/target/dependency/BOOT-INF/classes /app

EXPOSE 8080

ENTRYPOINT ["java", "-cp", "app:app/lib/*", "com.myapp.Application"]

6. Docker compose для локального развития

version: "3.8"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/mydb
      - SPRING_DATASOURCE_USERNAME=postgres
      - SPRING_DATASOURCE_PASSWORD=password
      - SPRING_PROFILES_ACTIVE=dev
    depends_on:
      - postgres
    networks:
      - app-network

  postgres:
    image: postgres:15-alpine
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network

volumes:
  postgres_data:

networks:
  app-network:

7. Команды для работы с образами

# Построить образ
docker build -t myapp:1.0.0 .

# Просмотреть все образы
docker images

# Запустить контейнер
docker run -d -p 8080:8080 --name myapp-container myapp:1.0.0

# Просмотреть логи
docker logs myapp-container
docker logs -f myapp-container

# Зайти в контейнер
docker exec -it myapp-container /bin/bash

# Остановить контейнер
docker stop myapp-container

# Удалить контейнер
docker rm myapp-container

# Удалить образ
docker rmi myapp:1.0.0

# Отправить образ в регистр
docker tag myapp:1.0.0 myregistry/myapp:1.0.0
docker push myregistry/myapp:1.0.0

8. .dockerignore файл

node_modules
.git
.gitignore
README.md
.env
.env.local
.vscode
.idea
*.log
target/
build/
dist/

9. Здоровье контейнера (HEALTHCHECK)

HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
    CMD curl -f http://localhost:8080/actuator/health || exit 1

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

  1. Используйте slim образы — openjdk:17-jre-slim вместо openjdk:17
  2. Multi-stage builds — уменьшает размер финального образа в 2-3 раза
  3. Запускайте от не-root пользователя — из соображений безопасности
  4. Кешируйте слои — копируйте зависимости отдельно от кода
  5. Устанавливайте HEALTHCHECK — для мониторинга здоровья контейнера
  6. Используйте .dockerignore — исключайте ненужные файлы
  7. Минимизируйте количество слоёв — каждый FROM, RUN, COPY создаёт слой
  8. Указывайте версию базового образа — не используйте latest

11. Размер образа

# Просмотреть размер образа
docker image ls myapp:1.0.0

# Анализ слоёв образа
docker history myapp:1.0.0

# Оптимизация: multi-stage обычно уменьшает размер с 1.5GB до 300-500MB

Таким образом, создание Docker образа — это стандартный процесс для упаковки Java приложений для production развёртывания.