Quarkus ImageBuild任务失败:容器镜像标签未正确替换
问题背景
基于Gradle构建的Quarkus项目,使用Multiverse Nyx自动管理版本,特性分支生成的版本格式类似0.1.0+commit.e5856.branch.featureJIRA12345MyChange——其中的+符号不符合容器镜像标签规范(镜像标签仅允许小写字母、数字、.、_、-),需要替换为-。
自定义Gradle任务处理版本后,processResources任务能正确替换application.yml中的变量,但执行imageBuild时始终报错:The supplied container-image tag '$sanitizedVersion' is invalid,且Quarkus有效配置中quarkus.container-image.tag的值为未解析的$sanitizedVersion字符串。
问题原因
Quarkus的容器镜像配置在Gradle配置阶段就会被读取,而原脚本中getSanitizedVersion任务的逻辑放在doLast块中——这部分代码要到任务执行阶段才会运行,导致Quarkus读取配置时,sanitizedVersion变量还未生成,配置中的$sanitizedVersion直接作为字符串传递,触发非法标签校验失败。
解决方案
将版本清洗逻辑提前到Gradle配置阶段执行,直接生成sanitizedVersion变量并覆盖Quarkus的容器镜像标签配置;同时保留资源文件的替换逻辑,确保application.yml正确更新。
修改后的Gradle脚本
def sanitizeVersionName(version) { // 替换所有非镜像标签允许的字符为连字符 return version.replaceAll("[^a-zA-Z0-9._-]", "-") } // 配置阶段直接生成清洗后的版本号 project.ext.sanitizedVersion = sanitizeVersionName(project.version) println "Sanitized Version: ${project.ext.sanitizedVersion}" // 直接覆盖Quarkus容器镜像标签配置 quarkus { containerImage { tag = project.ext.sanitizedVersion } } processResources { filesMatching(["application.yml"]) { println("Processing resource file: ${it.name}") expand([sanitizedVersion: project.ext.sanitizedVersion]) } }
代码说明
- 提前计算版本:移除原有的
getSanitizedVersion任务,直接在配置阶段调用清洗函数生成sanitizedVersion,确保Quarkus读取配置时变量已存在。 - 直接设置Quarkus配置:通过
quarkus.containerImage.tag直接指定标签值,避免配置文件中使用变量导致的延迟解析问题。 - 保留资源替换:
processResources中的expand逻辑不变,确保application.yml中的${sanitizedVersion}能被正确替换。
验证
执行镜像构建前,可先运行./gradlew properties查看quarkus.container-image.tag的值,确认已替换为清洗后的版本号,再执行./gradlew imageBuild即可成功构建镜像。
内容的提问来源于stack exchange,提问作者Hugo Dias

