Gradle Jib 容器化指南

使用 Jib 在 Gradle 專案中快速建構 Docker 映像,無需編寫 Dockerfile


目錄


Jib 簡介

什麼是 Jib?

Jib 是 Google 開發的 Java 容器化工具,可以直接從 Gradle/Maven 建構 Docker/OCI 映像,不需要 Docker daemon,也不需要編寫 Dockerfile。

核心優勢

特性 Jib 傳統 Dockerfile
需要 Docker ❌ 不需要 ✅ 需要
需要 Dockerfile ❌ 不需要 ✅ 需要
建構速度 ⚡ 快(增量建構) 🐢 慢
映像分層 ✅ 自動優化 ⚠️ 手動優化
可重現性 ✅ 完全可重現 ⚠️ 依賴基礎映像
整合度 ✅ 深度整合 Gradle ⚠️ 需要額外配置

Jib 的工作原理

Java 原始碼
Gradle 編譯
Jib 分析依賴
分層映像(自動優化)
├── 基礎層(JRE)
├── 依賴層(jar 檔案)
├── 資源層(resources)
└── 類別層(.class 檔案)
推送到 Registry

分層優勢

  • 修改程式碼只重建類別層
  • 新增依賴只重建依賴層
  • Docker 快取大幅減少建構時間

基本設定

1. 添加 Jib 插件

// build.gradle
plugins {
    id 'java'
    id 'com.google.cloud.tools.jib' version '3.4.0'
}

group = 'com.example'
version = '1.0.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web:3.0.0'
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

// Jib 基本配置
jib {
    from {
        image = 'eclipse-temurin:17-jre'  // 基礎映像
    }
    to {
        image = 'myapp'                   // 目標映像名稱
        tags = ['latest', project.version]
    }
    container {
        mainClass = 'com.example.Application'  // 主類別
        ports = ['8080']                  // 暴露的 port
    }
}

2. 建構映像

# 建構到本地 Docker
./gradlew jibDockerBuild

# 建構並推送到 Registry
./gradlew jib

# 建構到 tar 檔案
./gradlew jibBuildTar

Jib 配置詳解

完整配置結構

jib {
    from {
        // 基礎映像配置
    }
    to {
        // 目標映像配置
    }
    container {
        // 容器配置
    }
    extraDirectories {
        // 額外檔案配置
    }
}

from - 基礎映像配置

1. 基本用法

jib {
    from {
        image = 'eclipse-temurin:17-jre'  // OpenJDK 17
    }
}

2. Docker 鏡像標籤詳解

標籤組成結構

eclipse-temurin : 17 - jre - noble
     ↓            ↓    ↓     ↓
   鏡像名       Java版本 類型  OS版本

標籤各部分說明

部分 說明 常見值
Java 版本 JDK/JRE 主版本號 8, 11, 17, 21, 25
發行類型 開發工具 vs 運行環境 jdk (完整), jre (僅運行時)
OS 基礎 作業系統版本 noble, jammy, alpine, focal

OS 版本對照表

標籤後綴 作業系統 特性
noble Ubuntu 24.04 最新 LTS
jammy Ubuntu 22.04 穩定 LTS
focal Ubuntu 20.04 舊 LTS
alpine Alpine Linux 最小化 (~5-10MB)
無後綴 Ubuntu (最新) 默認選項

版本標籤範例

jib {
    from {
        // 1. 簡潔版本(默認 jdk + 最新 Ubuntu)
        image = 'eclipse-temurin:17'

        // 2. 指定 JDK/JRE
        image = 'eclipse-temurin:17-jdk'    // 開發用(包含編譯器)
        image = 'eclipse-temurin:17-jre'    // 生產用(僅運行時)

        // 3. 指定 OS(推薦用於生產環境)
        image = 'eclipse-temurin:17-jdk-noble'   // Ubuntu 24.04
        image = 'eclipse-temurin:17-jdk-jammy'   // Ubuntu 22.04
        image = 'eclipse-temurin:17-jre-alpine'  // Alpine(最小)

        // 4. 完整版本號(最佳實踐 - 確保可重現)
        image = 'eclipse-temurin:17.0.17_10-jdk-noble'
        image = 'eclipse-temurin:21.0.9_10-jre-alpine'
    }
}

如何查看可用版本

# 方法 1: Docker Hub 網頁查看(最直觀)
# https://hub.docker.com/_/eclipse-temurin/tags

# 方法 2: 使用 API 查詢
curl -s "https://registry.hub.docker.com/v2/repositories/library/eclipse-temurin/tags?page_size=100" \
  | grep -o '"name":"[^"]*"' | cut -d'"' -f4 | head -30

# 方法 3: 查看特定 Java 版本的所有變體
curl -s "https://registry.hub.docker.com/v2/repositories/library/eclipse-temurin/tags?page_size=100" \
  | grep -o '"name":"17[^"]*"' | cut -d'"' -f4 | sort

# 方法 4: 查看鏡像詳細資訊
docker manifest inspect eclipse-temurin:17-jdk-noble

版本選擇建議

使用場景 推薦標籤 原因
生產環境建構 17-jdk-noble 完整工具 + 穩定 OS
運行時容器 17-jre-alpine 最小體積(省資源)
開發調試 17-jdk 包含完整開發工具
CI/CD 17.0.17_10-jdk-noble 鎖定版本確保可重現
快速測試 17 快速開始(不考慮體積)

鏡像體積對比

# 實際體積參考(僅供參考,會隨版本變化)
eclipse-temurin:17-jdk          # ~450MB
eclipse-temurin:17-jdk-alpine   # ~320MB
eclipse-temurin:17-jre          # ~270MB
eclipse-temurin:17-jre-alpine   # ~170MB
gcr.io/distroless/java17        # ~150MB(最小)

標籤策略最佳實踐

jib {
    from {
        // ❌ 不推薦:過於寬泛,可能導致不可預測的更新
        image = 'eclipse-temurin:17'

        // ✅ 推薦:明確指定 OS 和類型
        image = 'eclipse-temurin:17-jdk-noble'

        // ✅ 最佳:鎖定完整版本號用於生產
        image = 'eclipse-temurin:17.0.17_10-jdk-noble'
    }
}

3. 常用基礎映像選擇

jib {
    from {
        // OpenJDK Eclipse Temurin(推薦 - 最廣泛使用)
        image = 'eclipse-temurin:17-jre-noble'      // Ubuntu 24.04
        image = 'eclipse-temurin:17-jre-alpine'     // Alpine(更小)

        // Amazon Corretto(AWS 環境推薦)
        image = 'amazoncorretto:17'
        image = 'amazoncorretto:17-alpine'

        // GraalVM(需要原生編譯)
        image = 'ghcr.io/graalvm/graalvm-ce:ol8-java17'

        // Distroless(最小化,無 shell,安全性最高)
        image = 'gcr.io/distroless/java17-debian11'
    }
}

3. 私有倉庫認證

jib {
    from {
        image = 'my-registry.com/base-image:latest'
        auth {
            username = project.findProperty('registryUser') ?: System.getenv('REGISTRY_USER')
            password = project.findProperty('registryPassword') ?: System.getenv('REGISTRY_PASSWORD')
        }
    }
}

4. 平台指定

jib {
    from {
        image = 'eclipse-temurin:17-jre'
        platforms {
            platform {
                architecture = 'amd64'
                os = 'linux'
            }
            platform {
                architecture = 'arm64'
                os = 'linux'
            }
        }
    }
}

to - 目標映像配置

1. 基本配置

jib {
    to {
        image = 'myapp'
        tags = ['latest', project.version, "${project.version}-${new Date().format('yyyyMMdd')}"]
    }
}

2. 推送到 Docker Hub

jib {
    to {
        image = 'docker.io/myusername/myapp'
        // 或簡寫
        image = 'myusername/myapp'

        tags = ['latest', '1.0.0']

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

3. 推送到私有 Registry

jib {
    to {
        image = 'my-registry.com:5000/myapp'
        tags = ['latest', project.version]

        auth {
            username = project.findProperty('registryUser')
            password = project.findProperty('registryPassword')
        }

        // 允許不安全的 registry(HTTP)
        // credHelper = 'osxkeychain'  // macOS
        // credHelper = 'wincred'      // Windows
        // credHelper = 'pass'         // Linux
    }
}

4. 推送到 AWS ECR

jib {
    to {
        image = '123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp'
        tags = ['latest']

        // ECR 使用 credential helper
        credHelper = 'ecr-login'
    }
}

5. 推送到 Google Container Registry (GCR)

jib {
    to {
        image = 'gcr.io/my-project/myapp'
        tags = ['latest']

        credHelper = 'gcr'
    }
}

container - 容器配置

1. 基本配置

jib {
    container {
        // 主類別
        mainClass = 'com.example.Application'

        // 暴露的 port
        ports = ['8080', '8443']

        // JVM 參數
        jvmFlags = [
            '-Xms256m',
            '-Xmx512m',
            '-XX:+UseG1GC',
            '-Dspring.profiles.active=prod'
        ]

        // 程式參數
        args = ['--server.port=8080']

        // 環境變數
        environment = [
            'JAVA_OPTS': '-Xmx512m',
            'APP_ENV': 'production'
        ]

        // 映像格式
        format = 'OCI'  // 或 'Docker'

        // 建立時間(用於可重現建構)
        creationTime = 'USE_CURRENT_TIMESTAMP'  // 或特定時間
    }
}

2. 使用者配置

jib {
    container {
        user = '1000:1000'  // UID:GID
        // 或
        user = 'appuser'

        // 工作目錄
        workingDirectory = '/app'
    }
}

3. 標籤(Labels)

jib {
    container {
        labels = [
            'maintainer': 'your-email@example.com',
            'version': project.version,
            'description': 'My Application',
            'org.opencontainers.image.source': 'https://github.com/user/repo'
        ]
    }
}

4. 容器啟動配置

jib {
    container {
        // 使用 shell 格式
        entrypoint = ['sh', '-c', 'java $JAVA_OPTS -jar app.jar']

        // 或使用預設的 Java entrypoint
        // entrypoint = 'INHERIT'  // 繼承基礎映像
    }
}

extraDirectories - 額外檔案

1. 添加靜態檔案

jib {
    extraDirectories {
        paths {
            path {
                from = file('src/main/jib')  // 來源目錄
                into = '/app'                // 容器中的目標路徑
            }
        }
    }
}

目錄結構

src/main/jib/
├── config/
│   └── application.properties
└── scripts/
    └── startup.sh

建構後在容器中:

/app/config/application.properties
/app/scripts/startup.sh

2. 多個來源目錄

jib {
    extraDirectories {
        paths {
            path {
                from = file('src/main/jib')
                into = '/app'
            }
            path {
                from = file('config')
                into = '/config'
            }
            path {
                from = file('scripts')
                into = '/scripts'
                includes = ['*.sh']  // 只包含 .sh 檔案
                excludes = ['test*.sh']  // 排除測試腳本
            }
        }
        permissions = [
            '/scripts/startup.sh': '755',  // 設定執行權限
            '/config/*': '644'
        ]
    }
}

常用指令

建構相關

# 建構到本地 Docker(需要 Docker daemon)
./gradlew jibDockerBuild

# 建構並推送到 Registry
./gradlew jib

# 建構到 tar 檔案
./gradlew jibBuildTar --image=myapp:1.0.0

# 載入 tar 到 Docker
docker load < build/jib-image.tar

參數覆寫

# 覆寫映像名稱
./gradlew jib --image=myregistry.com/myapp:v2

# 設定認證
./gradlew jib \
  -Djib.to.auth.username=myuser \
  -Djib.to.auth.password=mypass

# 覆寫基礎映像
./gradlew jib \
  -Djib.from.image=eclipse-temurin:17-jre-alpine

# 設定 JVM 參數
./gradlew jib \
  -Djib.container.jvmFlags=-Xmx1g,-Xms512m

除錯與資訊

# 顯示詳細日誌
./gradlew jib --info

# 顯示建構計畫(不實際建構)
./gradlew jibDockerBuild --dry-run

# 查看映像配置
./gradlew jib --console=plain

進階配置

1. 自訂分層

jib {
    // 自訂分層策略
    containerizingMode = 'packaged'  // 或 'exploded'(預設)

    container {
        // exploded: 展開 jar(更好的分層)
        // packaged: 保持 jar 格式
    }
}

2. 排除檔案

jib {
    extraDirectories {
        paths {
            path {
                from = file('src/main/resources')
                into = '/app/resources'
                excludes = [
                    '**/*.properties',  // 排除 properties 檔案
                    '**/test/**'        // 排除測試資源
                ]
            }
        }
    }
}

3. 離線模式

jib {
    allowInsecureRegistries = true  // 允許 HTTP registry

    // 使用本地快取的基礎映像
    from {
        image = 'eclipse-temurin:17-jre'
    }
}

離線建構

./gradlew jibDockerBuild --offline

4. 多環境配置

// 定義環境配置
def environments = [
    dev: [
        registry: 'localhost:5000',
        jvmFlags: ['-Xmx256m', '-Dspring.profiles.active=dev']
    ],
    prod: [
        registry: 'my-registry.com',
        jvmFlags: ['-Xmx1g', '-Dspring.profiles.active=prod']
    ]
]

// 從系統屬性或環境變數取得環境
def env = System.getProperty('env') ?: 'dev'
def config = environments[env]

jib {
    to {
        image = "${config.registry}/myapp"
        tags = ['latest', project.version]
    }
    container {
        jvmFlags = config.jvmFlags
    }
}

使用

# 開發環境
./gradlew jib -Denv=dev

# 生產環境
./gradlew jib -Denv=prod

5. Spring Boot 整合

plugins {
    id 'org.springframework.boot' version '3.0.0'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
    id 'com.google.cloud.tools.jib' version '3.4.0'
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

jib {
    from {
        image = 'eclipse-temurin:17-jre'
    }
    to {
        image = 'myapp'
    }
    container {
        // Spring Boot 會自動設定 mainClass
        ports = ['8080']
        jvmFlags = [
            '-Dspring.profiles.active=prod',
            '-XX:+UseContainerSupport',
            '-XX:MaxRAMPercentage=75.0'
        ]

        // Spring Boot 特定配置
        environment = [
            'SPRING_OUTPUT_ANSI_ENABLED': 'ALWAYS'
        ]
    }
}

多階段建構

概念

Jib 本身不需要多階段建構(因為不使用 Dockerfile),但可以模擬類似效果:

// build.gradle

// 定義建構任務
task buildDev {
    doLast {
        exec {
            commandLine './gradlew', 'jib',
                '-Djib.to.image=myapp:dev',
                '-Djib.container.jvmFlags=-Xmx256m,-Dspring.profiles.active=dev'
        }
    }
}

task buildProd {
    doLast {
        exec {
            commandLine './gradlew', 'jib',
                '-Djib.to.image=myapp:prod',
                '-Djib.container.jvmFlags=-Xmx1g,-Dspring.profiles.active=prod'
        }
    }
}

實際應用範例

範例 1:簡單 Spring Boot 應用

// build.gradle
plugins {
    id 'org.springframework.boot' version '3.0.0'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
    id 'com.google.cloud.tools.jib' version '3.4.0'
}

group = 'com.example'
version = '1.0.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
}

jib {
    from {
        image = 'eclipse-temurin:17-jre-alpine'
    }
    to {
        image = 'myapp'
        tags = ['latest', project.version]
    }
    container {
        ports = ['8080']
        jvmFlags = [
            '-Xms256m',
            '-Xmx512m',
            '-Dspring.profiles.active=prod'
        ]
        creationTime = 'USE_CURRENT_TIMESTAMP'
    }
}

建構

./gradlew jibDockerBuild
docker run -p 8080:8080 myapp:latest

範例 2:推送到 Docker Hub

jib {
    from {
        image = 'eclipse-temurin:17-jre'
    }
    to {
        image = 'docker.io/myusername/myapp'
        tags = ['latest', "${project.version}"]
        auth {
            username = System.getenv('DOCKER_USERNAME')
            password = System.getenv('DOCKER_PASSWORD')
        }
    }
    container {
        ports = ['8080']
        labels = [
            'maintainer': 'your-email@example.com',
            'version': project.version
        ]
    }
}

使用

# 設定環境變數
export DOCKER_USERNAME=myusername
export DOCKER_PASSWORD=mypassword

# 建構並推送
./gradlew jib

範例 3:包含配置檔案

專案結構

myproject/
├── build.gradle
├── src/
│   └── main/
│       ├── java/
│       └── jib/
│           ├── config/
│           │   └── application.yml
│           └── scripts/
│               └── startup.sh

build.gradle

jib {
    from {
        image = 'eclipse-temurin:17-jre'
    }
    to {
        image = 'myapp'
    }
    container {
        ports = ['8080']
        entrypoint = ['/scripts/startup.sh']
    }
    extraDirectories {
        paths {
            path {
                from = file('src/main/jib')
                into = '/'
            }
        }
        permissions = [
            '/scripts/startup.sh': '755'
        ]
    }
}

startup.sh

#!/bin/sh
echo "Starting application..."
java $JAVA_OPTS -jar /app/app.jar

範例 4:多模組專案

// 根 build.gradle
subprojects {
    apply plugin: 'java'
    apply plugin: 'com.google.cloud.tools.jib'

    jib {
        from {
            image = 'eclipse-temurin:17-jre'
        }
        to {
            image = "myregistry.com/${project.name}"
            tags = [project.version]
        }
    }
}
// api/build.gradle
jib {
    container {
        mainClass = 'com.example.api.ApiApplication'
        ports = ['8080']
    }
}
// worker/build.gradle
jib {
    container {
        mainClass = 'com.example.worker.WorkerApplication'
    }
}

建構

# 建構所有模組
./gradlew jib

# 建構特定模組
./gradlew :api:jib
./gradlew :worker:jib

與 Dockerfile 比較

Dockerfile 方式

# Dockerfile
FROM eclipse-temurin:17-jre

WORKDIR /app

COPY build/libs/myapp.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]
# 需要先建構 jar
./gradlew build

# 建構映像
docker build -t myapp .

# 推送
docker push myapp

問題

  • 需要 Docker daemon
  • 分層不夠細緻(整個 jar 是一層)
  • 修改程式碼需要重建整個 jar 層

Jib 方式

// build.gradle
jib {
    from {
        image = 'eclipse-temurin:17-jre'
    }
    to {
        image = 'myapp'
    }
    container {
        ports = ['8080']
    }
}
# 一個指令完成所有事情
./gradlew jib

優勢

  • 不需要 Docker
  • 自動分層優化
  • 增量建構(快)

分層對比

Dockerfile

Layer 1: 基礎映像
Layer 2: 整個 jar 檔案(包含所有依賴和程式碼)

Jib

Layer 1: 基礎映像
Layer 2: 依賴 jar(很少改變)
Layer 3: 資源檔案
Layer 4: 類別檔案(經常改變)

修改程式碼時:

  • Dockerfile:重建 Layer 2(整個 jar)
  • Jib:只重建 Layer 4(類別檔案)

疑難排解

1. 無法連接到 Registry

錯誤

Error: Cannot connect to registry

解決

jib {
    allowInsecureRegistries = true  // 允許 HTTP

    to {
        image = 'localhost:5000/myapp'
    }
}

2. 認證失敗

錯誤

Error: 401 Unauthorized

解決

# 方式 1:使用環境變數
export DOCKER_USERNAME=myuser
export DOCKER_PASSWORD=mypass

# 方式 2:使用 credential helper
./gradlew jib -Djib.to.credHelper=osxkeychain

# 方式 3:使用 gradle.properties
echo "registryUser=myuser" >> gradle.properties
echo "registryPassword=mypass" >> gradle.properties

3. 找不到主類別

錯誤

Error: Main class was not found

解決

jib {
    container {
        mainClass = 'com.example.Application'  // 明確指定
    }
}

// 或在 application 插件中指定
application {
    mainClass = 'com.example.Application'
}

4. 記憶體不足

錯誤

OutOfMemoryError during build

解決

# 增加 Gradle 記憶體
export GRADLE_OPTS="-Xmx2g"

# 或在 gradle.properties
org.gradle.jvmargs=-Xmx2g

5. 映像太大

問題:映像檔案過大

解決

jib {
    from {
        // 使用更小的基礎映像
        image = 'eclipse-temurin:17-jre-alpine'  // Alpine 版本
        // 或
        image = 'gcr.io/distroless/java17-debian11'  // Distroless
    }

    // 排除不必要的檔案
    extraDirectories {
        paths {
            path {
                from = file('src/main/resources')
                excludes = ['**/*.md', '**/test/**']
            }
        }
    }
}

6. 查看建構的映像資訊

# 檢查映像
docker images myapp

# 查看映像歷史(分層)
docker history myapp:latest

# 檢查映像內容
docker run --rm myapp:latest ls -la /app

最佳實踐

1. 使用輕量基礎映像

推薦

jib {
    from {
        // Alpine(小但完整)
        image = 'eclipse-temurin:17-jre-alpine'

        // Distroless(最小化)
        image = 'gcr.io/distroless/java17-debian11'
    }
}

避免:使用完整的 JDK 映像

// 不必要地大
image = 'eclipse-temurin:17'

2. 設定記憶體限制

jib {
    container {
        jvmFlags = [
            '-XX:+UseContainerSupport',      // 偵測容器環境
            '-XX:MaxRAMPercentage=75.0',     // 使用 75% 容器記憶體
            '-XX:InitialRAMPercentage=50.0'  // 初始 50%
        ]
    }
}

3. 使用環境變數

jib {
    to {
        auth {
            username = System.getenv('REGISTRY_USER')
            password = System.getenv('REGISTRY_PASSWORD')
        }
    }
    container {
        environment = [
            'JAVA_OPTS': '-Xmx512m',
            'APP_ENV': System.getenv('APP_ENV') ?: 'production'
        ]
    }
}

4. 版本標籤策略

jib {
    to {
        image = 'myapp'
        tags = [
            'latest',
            project.version,
            "${project.version}-${new Date().format('yyyyMMdd-HHmm')}",
            System.getenv('GIT_COMMIT')?.substring(0, 7) ?: 'dev'
        ]
    }
}

5. 可重現建構

jib {
    container {
        // 使用固定時間戳記
        creationTime = '1970-01-01T00:00:00Z'

        // 或使用當前時間
        creationTime = 'USE_CURRENT_TIMESTAMP'
    }
}

6. CI/CD 整合

# .github/workflows/build.yml
name: Build and Push

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

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

      - name: Build and push with Jib
        env:
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
        run: |
          ./gradlew jib \
            -Djib.to.image=docker.io/${{ secrets.DOCKER_USERNAME }}/myapp \
            -Djib.to.auth.username=${{ secrets.DOCKER_USERNAME }} \
            -Djib.to.auth.password=${{ secrets.DOCKER_PASSWORD }}

7. 本地測試流程

# 1. 建構到本地 Docker
./gradlew jibDockerBuild

# 2. 執行容器
docker run -p 8080:8080 myapp:latest

# 3. 測試
curl http://localhost:8080/health

# 4. 查看日誌
docker logs <container-id>

# 5. 進入容器除錯
docker exec -it <container-id> sh

總結

Jib 的核心優勢

  1. 不需要 Docker:可以在沒有 Docker 的環境建構映像
  2. 快速建構:增量建構和智慧分層
  3. 簡單配置:不需要編寫 Dockerfile
  4. 自動優化:自動分層優化,最大化快取效益
  5. 可重現性:完全可重現的建構

適用場景

適合使用 Jib

  • Java/Kotlin 應用程式
  • Spring Boot 專案
  • 需要快速建構的 CI/CD 環境
  • 不想維護 Dockerfile

不適合使用 Jib

  • 需要複雜的自訂建構步驟
  • 非 Java 應用程式
  • 需要在容器中安裝系統套件

快速指令參考

# 建構到本地 Docker
./gradlew jibDockerBuild

# 建構並推送
./gradlew jib

# 建構到 tar
./gradlew jibBuildTar

# 覆寫映像名稱
./gradlew jib --image=myregistry.com/myapp:v2

# 顯示詳細日誌
./gradlew jib --info

建立日期:2025-11-03 最後更新:2025-11-18

🔗相關文章