You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle Jib在GitHub Workflow中无法认证GHCR,本地为何也随即失败?

问题分析与解决

现象描述

本地可通过Gradle Jib构建并推送容器镜像至GitHub容器注册表(GHCR),但GitHub Workflow执行相同操作时失败;更特殊的是,Workflow失败后,本地再用同一个令牌执行构建也会报相同错误,必须重新生成GitHub个人访问令牌才能恢复正常。

复现步骤

    1. build.gradle配置如下:
plugins {
    id 'java'
    id 'idea'
    id 'org.springframework.boot' version '3.0.1'
    id 'com.google.cloud.tools.jib' version '3.3.1'
    id 'io.spring.dependency-management' version '1.1.0'
 }

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

 compileJava.options.encoding = "UTF-8"
 compileTestJava.options.encoding = "UTF-8"

 configurations {
   published
   compileOnly {
     extendsFrom annotationProcessor
   }
 }

 dependencies {
   implementation 'org.springframework.boot:spring-boot-starter-web'
   annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
   testImplementation('org.assertj:assertj-core')
   testImplementation('org.junit.jupiter:junit-jupiter-api')
   testRuntimeOnly('org.junit.jupiter:junit-jupiter-engine')
 }


 tasks.withType(Test) {
   useJUnitPlatform()
 }

 task prepareKotlinBuildScriptModel {
 }

 springBoot {
   buildInfo()
 }

 bootJar {
   enabled = false
 }

 jar {
   enabled = true
 }

 def baseImage = 'ghcr.io/tobias-neubert/eclipse-temurin:17.0.2_8-jre'
 jib {
   from {
     image = baseImage
     auth {
       username = "tobias-neubert"
       password = "${System.getenv("GITHUB_PASSWORD")}"
     }
   }
   to {
     image = 'ghcr.io/tobias-neubert/motd-service'
     auth {
       username = "tobias-neubert"
       password = "${System.getenv("GITHUB_PASSWORD")}"
     }
   }
   container {
     mainClass = 'com.neubert.scaffold.motdservice.MotdServiceApplication'
     ports = ['8080']
   }
 }
    1. 在GitHub创建新的个人访问令牌(PAT)。
    1. 本地执行命令:GITHUB_PASSWORD=<personal-access-token> ./gradlew :motd-service:jib
    1. 镜像成功推送至GHCR,重复本地构建也能成功。
    1. GitHub Workflow配置如下:
name: Build and push motd-service

on:
  push:
    branches:
      - actions

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Set up Java
        uses: actions/setup-java@v2
        with:
          java-version: 17
          distribution: temurin

      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2

      - name: Make gradlew executable
        run: chmod +x ./gradlew

      - name: Build the motd image
        run: |
          GITHUB_PASSWORD=<personal-access-token> ./gradlew :motd-service:jib
    1. Workflow执行失败,报错:
Execution failed for task ':motd-service:jib'.
> com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: Build image failed, perhaps you should make sure you have permissions for ghcr.io/tobias-neubert/eclipse-temurin and set correct credentials.
    1. 再次本地执行相同构建命令,也出现上述错误。

问题根源

  1. 令牌泄露被自动吊销:Workflow中直接硬编码个人访问令牌,提交到仓库后,GitHub会检测到日志或代码中的令牌并自动吊销——这就是Workflow失败后本地也无法使用同一令牌的核心原因。
  2. 不必要的基础镜像认证:如果ghcr.io/tobias-neubert/eclipse-temurin是公共镜像,拉取时无需认证,硬加认证反而可能触发权限校验错误。
  3. 令牌权限不足:创建个人访问令牌时,未授予足够的权限(如write:packages、read:packages),导致推送/拉取镜像操作失败。

解决方案

1. 修复Workflow的令牌使用方式

绝对禁止在Workflow中硬编码令牌,改用GitHub Secrets存储:

  • 进入仓库的Settings → Secrets and variables → Actions,点击New repository secret,创建名为GITHUB_PASSWORD的Secret,值为你的个人访问令牌。
  • 修改Workflow的构建步骤:
- name: Build the motd image
  run: |
    GITHUB_PASSWORD=${{ secrets.GITHUB_PASSWORD }} ./gradlew :motd-service:jib

2. 移除基础镜像的不必要认证

如果基础镜像ghcr.io/tobias-neubert/eclipse-temurin是公开的,删除jib.from.auth配置:

jib {
  from {
    image = baseImage
    // 删除auth块
  }
  // to部分的auth保留
}

3. 确保令牌权限足够

创建个人访问令牌时,勾选以下权限:

  • write:packages(推送镜像)
  • read:packages(拉取镜像)
  • repo(若为私有仓库)

4. 推荐使用GitHub Actions内置的GITHUB_TOKEN

无需手动创建个人令牌,GitHub Actions提供临时的GITHUB_TOKEN,默认拥有当前仓库的packages操作权限:

  • 修改Workflow的构建步骤:
- name: Build the motd image
  env:
    GITHUB_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
    GITHUB_USERNAME: github-actions[bot]
  run: ./gradlew :motd-service:jib
  • 同步修改build.gradle的auth配置,兼容两种令牌场景:
jib {
  from {
    image = baseImage
  }
  to {
    image = 'ghcr.io/tobias-neubert/motd-service'
    auth {
      username = System.getenv("GITHUB_USERNAME") ?: "tobias-neubert"
      password = System.getenv("GITHUB_PASSWORD")
    }
  }
  // container部分不变
}

内容的提问来源于stack exchange,提问作者Tobias Neubert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:35:28