スキル一覧に戻る
dawiddutoit

gradle-docker-jib

by dawiddutoit

Collection of Claude Code skills, agents, and plugins

0🍴 0📅 2026年1月20日
GitHubで見るManusで実行

SKILL.md


name: gradle-docker-jib description: | Build optimized Docker images using Jib without Docker or Dockerfile. Use when containerizing Spring Boot microservices, building multi-architecture images, or pushing to registries. Includes Jib setup, multi-module configuration, and CI/CD integration.

Gradle Docker Jib Integration

Table of Contents

Purpose

Build Docker images efficiently using Google's Jib plugin without requiring Docker installation, Dockerfiles, or any container knowledge. Jib automatically optimizes layers and handles multi-architecture builds for both local and registry deployments.

When to Use

Use this skill when you need to:

  • Build Docker images without Docker daemon or Dockerfiles
  • Containerize Spring Boot microservices efficiently
  • Create multi-architecture images (amd64, arm64) for cloud deployment
  • Optimize Docker layer caching for faster builds
  • Push images to GCR, Docker Hub, or private registries
  • Integrate Docker image building in CI/CD pipelines
  • Configure JVM settings and container runtime parameters

Quick Start

Add Jib plugin to build.gradle.kts:

plugins {
    id("com.google.cloud.tools.jib") version "3.4.4"
}

jib {
    from {
        image = "eclipse-temurin:21-jre-alpine"
    }

    to {
        image = "gcr.io/my-project/my-app"
        tags = setOf("latest", project.version.toString())
    }

    container {
        jvmFlags = listOf("-Xms512m", "-Xmx2048m")
        ports = listOf("8080")
        user = "1000:1000"
    }
}

Build and push:

./gradlew jib                    # Build and push to registry
./gradlew jibDockerBuild         # Build to local Docker daemon
./gradlew jibBuildTar            # Build as tar file

Instructions

Step 1: Add Jib Plugin

Add to build.gradle.kts:

plugins {
    id("com.google.cloud.tools.jib") version "3.4.4"
}

Or use version catalog (recommended for multi-module):

plugins {
    alias(libs.plugins.jib)
}

Step 2: Configure Base Image

Choose appropriate base image for your application:

jib {
    from {
        // Lightweight JRE (recommended for Spring Boot)
        image = "eclipse-temurin:21-jre-alpine"

        // Or standard JRE
        image = "eclipse-temurin:21-jre"

        // Or JDK (if needed)
        image = "eclipse-temurin:21-jdk-alpine"

        // Multi-architecture support (amd64, arm64)
        platforms {
            platform {
                architecture = "amd64"
                os = "linux"
            }
            platform {
                architecture = "arm64"
                os = "linux"
            }
        }
    }
}

Step 3: Configure Target Registry

Set up target image location and authentication:

jib {
    to {
        // Google Container Registry (GCR)
        image = "gcr.io/my-project/supplier-charges-hub"

        // Or Docker Hub
        image = "docker.io/mycompany/supplier-charges-hub"

        // Or private registry
        image = "registry.company.com/supplier-charges-hub"

        // Tags (version + latest)
        tags = setOf("latest", project.version.toString())

        // Authentication (from environment variables)
        auth {
            username = System.getenv("DOCKER_USERNAME")
            password = System.getenv("DOCKER_PASSWORD")
        }
    }
}

Step 4: Configure Container Runtime

Set JVM arguments, ports, and environment:

jib {
    container {
        // JVM flags for optimal performance
        jvmFlags = listOf(
            "-Xms512m",                           // Initial heap
            "-Xmx2048m",                          // Max heap
            "-XX:+UseG1GC",                       // Garbage collector
            "-XX:MaxGCPauseMillis=200",           // GC pause time
            "-Djava.security.egd=file:/dev./urandom"  // Entropy
        )

        // Exposed ports
        ports = listOf("8080", "8081")

        // Environment variables
        environment = mapOf(
            "SPRING_PROFILES_ACTIVE" to "production",
            "JAVA_TOOL_OPTIONS" to "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
        )

        // Image labels for metadata
        labels = mapOf(
            "maintainer" to "platform-team@company.com",
            "version" to project.version.toString()
        )

        // Non-root user (security best practice)
        user = "1000:1000"

        // Reproducible builds (EPOCH = timestamp 0)
        creationTime = "EPOCH"  // Or "USE_CURRENT_TIMESTAMP"
    }
}

Step 5: Configure Extra Files (Optional)

Add configuration files to the container:

jib {
    extraDirectories {
        paths {
            path {
                from = file("src/main/jib")
                into = "/app/config"
            }
        }
    }
}

Create files in src/main/jib/app/config/:

src/main/jib/
└── app/
    └── config/
        ├── application-prod.yml
        └── logback.xml

Step 6: Handle Authentication

Environment variables (recommended):

jib {
    to {
        auth {
            username = System.getenv("DOCKER_USERNAME")
            password = System.getenv("DOCKER_PASSWORD")
        }
    }
}

Docker config (from ~/.docker/config.json):

# Login once
docker login -u username -p password gcr.io

# Jib will automatically use stored credentials
./gradlew jib

Gradle properties (fallback):

# gradle.properties
jibTo.username=myuser
jibTo.password=mytoken

Step 7: Multi-Module Configuration

Configure common Jib settings in root build.gradle.kts:

// Root build.gradle.kts
subprojects {
    plugins.withId("com.google.cloud.tools.jib") {
        configure<com.google.cloud.tools.jib.gradle.JibExtension> {
            from {
                image = "eclipse-temurin:21-jre-alpine"
            }

            to {
                image = "gcr.io/my-project/${project.name}"
                tags = setOf("latest", rootProject.version.toString())

                auth {
                    username = System.getenv("DOCKER_USERNAME")
                    password = System.getenv("DOCKER_PASSWORD")
                }
            }

            container {
                jvmFlags = listOf(
                    "-Xms512m",
                    "-Xmx2048m",
                    "-XX:+UseContainerSupport"
                )

                ports = listOf("8080")
                user = "1000:1000"
                creationTime = "EPOCH"
            }
        }
    }
}

Each module can override with specific settings:

// supplier-charges-hub/build.gradle.kts
configure<com.google.cloud.tools.jib.gradle.JibExtension> {
    container {
        ports = listOf("8080", "8081")  // Additional port
        jvmFlags = listOf(
            "-Xms512m",
            "-Xmx3048m"  // More memory for this service
        )
    }
}

Examples

Example 1: Complete Jib Configuration

// build.gradle.kts
plugins {
    id("java")
    id("org.springframework.boot") version "3.5.5"
    id("io.spring.dependency-management") version "1.1.7"
    id("com.google.cloud.tools.jib") version "3.4.4"
}

group = "com.waitrose"
version = "1.0.0"

jib {
    // Base image
    from {
        image = "eclipse-temurin:21-jre-alpine"
        platforms {
            platform { architecture = "amd64"; os = "linux" }
            platform { architecture = "arm64"; os = "linux" }
        }
    }

    // Target registry
    to {
        image = "gcr.io/supplier-charges/supplier-charges-hub"
        tags = setOf("latest", "v${project.version}", "stable")

        auth {
            username = System.getenv("DOCKER_USERNAME")
            password = System.getenv("DOCKER_PASSWORD")
        }
    }

    // Container configuration
    container {
        jvmFlags = listOf(
            "-Xms512m",
            "-Xmx2048m",
            "-XX:+UseG1GC",
            "-XX:MaxGCPauseMillis=200",
            "-Djava.security.egd=file:/dev./urandom",
            "-XX:+UseContainerSupport",
            "-XX:MaxRAMPercentage=75.0"
        )

        ports = listOf("8080", "8081")  // 8080: app, 8081: actuator

        environment = mapOf(
            "SPRING_PROFILES_ACTIVE" to "production",
            "LOG_LEVEL" to "INFO",
            "TZ" to "UTC"
        )

        labels = mapOf(
            "maintainer" to "platform-team@waitrose.com",
            "app.version" to "${project.version}",
            "app.name" to "${project.name}",
            "build.date" to System.currentTimeMillis().toString()
        )

        // Non-root user
        user = "1000:1000"

        // Reproducible builds
        creationTime = "EPOCH"
    }

    // Extra files
    extraDirectories {
        paths {
            path {
                from = file("src/main/jib")
                into = "/app/config"
            }
        }
    }
}

Example 2: Multi-Architecture Build

jib {
    from {
        image = "eclipse-temurin:21-jre-alpine"
        platforms {
            // Build for both AMD64 and ARM64
            platform {
                architecture = "amd64"
                os = "linux"
            }
            platform {
                architecture = "arm64"  // Apple Silicon, AWS Graviton2
                os = "linux"
            }
        }
    }

    to {
        image = "gcr.io/my-project/my-app"
        tags = setOf("latest", "${project.version}")
    }
}

Build:

# Builds both architectures and pushes
./gradlew jib

# For local testing
./gradlew jibDockerBuild
# Then check available architectures
docker image inspect my-app:latest | grep -A 5 Architecture

Example 3: CI/CD Integration with GitHub Actions

# .github/workflows/docker-build.yml
name: Build and Push Docker Image

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Set up JDK 21
      uses: actions/setup-java@v4
      with:
        java-version: '21'
        distribution: 'temurin'

    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@v4

    - name: Build Docker Image with Jib
      run: ./gradlew jib
      if: github.ref == 'refs/heads/main'
      env:
        DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
        DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build Local Docker Image (PR)
      run: ./gradlew jibDockerBuild
      if: github.ref != 'refs/heads/main'

Example 4: GitLab CI/CD Integration

# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

variables:
  GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.caching=true"

build-image:
  stage: deploy
  image: gradle:8.11-jdk21-alpine
  only:
    - main
  script:
    - chmod +x ./gradlew
    - ./gradlew jib
      -Djib.to.auth.username=$DOCKER_USERNAME
      -Djib.to.auth.password=$DOCKER_PASSWORD
  environment:
    name: production

Example 5: Local Testing Before Push

# Build to local Docker daemon (requires Docker)
./gradlew jibDockerBuild

# Test locally
docker run -p 8080:8080 supplier-charges-hub:latest

# Access application
curl http://localhost:8080/actuator/health

# Check image size
docker images supplier-charges-hub
# REPOSITORY                SIZE
# supplier-charges-hub:latest  250MB

Example 6: Debugging Image Contents

# Build as tar file
./gradlew jibBuildTar --image=supplier-charges-hub:latest

# Extract and inspect
mkdir image-contents
cd image-contents
tar xf ../build/jib-image.tar

# Browse layers
ls -la
# app/
# config/
# layers/

Example 7: Multi-Module with Shared Configuration

// Root build.gradle.kts
subprojects {
    plugins.withId("com.google.cloud.tools.jib") {
        configure<com.google.cloud.tools.jib.gradle.JibExtension> {
            from {
                image = "eclipse-temurin:21-jre-alpine"
                platforms {
                    platform { architecture = "amd64"; os = "linux" }
                    platform { architecture = "arm64"; os = "linux" }
                }
            }

            to {
                image = "gcr.io/my-company/${project.name}"
                tags = setOf("latest", rootProject.version.toString())

                auth {
                    username = System.getenv("DOCKER_USERNAME")
                    password = System.getenv("DOCKER_PASSWORD")
                }
            }

            container {
                jvmFlags = listOf(
                    "-Xms512m",
                    "-Xmx2048m",
                    "-XX:+UseContainerSupport",
                    "-XX:MaxRAMPercentage=75.0"
                )

                user = "1000:1000"
                creationTime = "EPOCH"
            }
        }
    }
}

Commands Reference

# === BUILDING ===

# Build and push to registry
./gradlew jib

# Build to local Docker daemon (requires Docker)
./gradlew jibDockerBuild

# Build as tar file (no Docker needed)
./gradlew jibBuildTar

# Dry run (show what would be done)
./gradlew jib --dry-run

# === CONFIGURATION ===

# Override base image via command line
./gradlew jib -Djib.from.image=eclipse-temurin:21-jdk-alpine

# Override target image
./gradlew jib -Djib.to.image=gcr.io/my-project/my-app

# Override tags
./gradlew jib -Djib.to.tags=latest,v1.0.0

# === DEBUGGING ===

# Verbose output
./gradlew jib --info

# Very verbose output
./gradlew jib --debug

# Show what would be built
./gradlew jib --dry-run --info

Troubleshooting

Authentication failures:

  • Ensure credentials are set: DOCKER_USERNAME, DOCKER_PASSWORD
  • Test with docker login: docker login -u $DOCKER_USERNAME gcr.io
  • Check credentials haven't expired

Image too large:

  • Use -alpine base images (much smaller)
  • Verify only needed dependencies in build
  • Check layering in container { jvmFlags } config

Multi-architecture build fails:

  • Ensure registry supports multi-arch (GCR, Docker Hub do)
  • Check platforms configuration includes both amd64 and arm64
  • Use ./gradlew jibDockerBuild first for single-arch testing

Permission denied - non-root user:

  • Verify user = "1000:1000" is set
  • Ensure application can write to needed directories
  • Run as numeric UID (not username) for Kubernetes compatibility

Slow builds:

  • Enable Gradle build cache: org.gradle.caching=true
  • Use configuration cache: org.gradle.configuration-cache=true
  • Run with --parallel

Image Best Practices

  • Use -jre-alpine base images (smallest, recommended)
  • Set creationTime = "EPOCH" for reproducible builds
  • Use non-root user: user = "1000:1000"
  • Configure container memory for Kubernetes: -XX:MaxRAMPercentage=75.0
  • Tag with version AND commit SHA for traceability
  • Keep JVM flags minimal (only production-critical ones)
  • Add labels for monitoring and debugging

See Also

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です