Chuyển đến nội dung chính

レッスン 21: Spring Boot の Docker とコンテナ化

Dockerfile のマルチステージ ビルド。 Spring Boot ビルドパック (クラウド ネイティブ ビルドパック)。開発用の Docker Compose。 GraalVM ネイティブ イメージ。コンテナのベストプラクティス。

💻 プログラミング — レッスン 20 レッスン 21: Docker とコンテナ化 スプリングブーツ

Spring Boot 4: 基本から上級まで

パート 6: マイクロサービスとプロダクション

xdev.asia

はじめに

コンテナー化は、Spring Boot アプリケーションを実稼働環境に導入するための最初のステップです。この記事では、基本的な Dockerfile からマルチステージ ビルド、Cloud Native Buildpack、GraalVM Native Image、ローカル開発用の Docker Compose までを説明します。


1. Dockerfile のマルチステージビルド

1.1 基本的な Dockerfile

# Stage 1: Build
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY gradle/ gradle/
COPY gradlew build.gradle.kts settings.gradle.kts ./
RUN ./gradlew dependencies --no-daemon
COPY src/ src/
RUN ./gradlew bootJar --no-daemon -x test

# Stage 2: Runtime
FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

1.2 最適化された階層化 Dockerfile

Spring Boot は階層化された JAR を作成し、Docker が効果的にキャッシュできるようにします。

FROM eclipse-temurin:21-jre-alpine AS builder
WORKDIR /app
COPY build/libs/*.jar app.jar
RUN java -Djarmode=tools -jar app.jar extract --layers --destination extracted

FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S app && adduser -S app -G app
WORKDIR /app
COPY --from=builder /app/extracted/dependencies/ ./
COPY --from=builder /app/extracted/spring-boot-loader/ ./
COPY --from=builder /app/extracted/snapshot-dependencies/ ./
COPY --from=builder /app/extracted/application/ ./
USER app
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

2. クラウドネイティブ ビルドパック

Spring Boot はビルドパックをサポートしています - Dockerfile を使用せずに Docker イメージを作成します。

# Gradle
./gradlew bootBuildImage --imageName=myapp:latest

# Maven
./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=myapp:latest
// build.gradle.kts — Customize
tasks.bootBuildImage {
    imageName.set("registry.example.com/myapp:${version}")
    environment.set(mapOf(
        "BP_JVM_VERSION" to "21",
        "BPE_JAVA_TOOL_OPTIONS" to "-XX:MaxRAMPercentage=75"
    ))
}

3. GraalVM ネイティブ イメージ

3.1 ネイティブ イメージのビルド

// build.gradle.kts
plugins {
    id("org.graalvm.buildtools.native") version "0.10.6"
}
# Build native executable
./gradlew nativeCompile

# Build native Docker image
./gradlew bootBuildImage --imageName=myapp-native:latest

3.2 JVM とネイティブの比較

メトリクスJVMネイティブイメージ
起動時間2-5秒50~200ミリ秒
メモリ (RSS)200-400MB50~100MB
ビルド時間10~30代3~10分
ピークスループット最高~10 ~ 20% 低い
こんな方に最適長期にわたるサービスサーバーレス、CLI

4. 開発用の Docker Compose

# docker-compose.yml
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: docker
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/myapp
      SPRING_DATASOURCE_USERNAME: postgres
      SPRING_DATASOURCE_PASSWORD: postgres
      SPRING_DATA_REDIS_HOST: redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  db:
    image: postgres:17-alpine
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:

4.1 Spring Boot Docker Compose のサポート

// build.gradle.kts
developmentOnly("org.springframework.boot:spring-boot-docker-compose")
# application.yml
spring:
  docker:
    compose:
      lifecycle-management: start-and-stop
      file: docker-compose.yml

Spring Boot は、アプリの実行時に Docker Compose を自動的に起動し、接続プロパティを構成します。


5. コンテナのベストプラクティス

5.1 コンテナ用の JVM チューニング

ENTRYPOINT ["java", \
  "-XX:MaxRAMPercentage=75", \
  "-XX:+UseZGC", \
  "-XX:+ZGenerational", \
  "-Djava.security.egd=file:/dev/./urandom", \
  "-jar", "app.jar"]

5.2 Docker でのヘルスチェック

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:8080/actuator/health || exit 1

5.3 .dockerignore

.git
.gradle
build/
!build/libs/*.jar
.idea
*.iml
node_modules

概要

  • マルチステージ Dockerfile: ビルド ステージとランタイム ステージを分離し、イメージ サイズを大幅に削減します。
  • クラウド ネイティブ ビルドパック: Dockerfile を使用せずに Docker イメージを作成します。 ./gradlew bootBuildImage
  • GraalVM ネイティブ イメージ: 起動 50 ~ 200 ミリ秒、メモリ 50 ~ 100MB — サーバーレスに最適
  • Docker Compose + Spring Boot Docker Compose サポート: 開発時に依存関係を自動的に開始します

演習

  1. 階層化抽出を使用して Spring Boot アプリ用のマルチステージ Dockerfile を作成します。シングルステージとの画像サイズの比較
  2. 完全な docker-compose.yml を作成します: app + PostgreSQL + Redis。 healthcheck と depend_on を構成する
  3. GraalVM Native Imageを構築し、起動時間とメモリ使用量を測定し、JVMモードと比較します。