Jenkins构建Docker镜像推送到AWS ECR报错及代码简化求助
修复Jenkins流水线构建推送AWS ECR的错误并简化代码
错误原因分析
你遇到的Bad substitution错误来自两个核心问题:
- Shell变量赋值语法错误:
REPOSITORY_URI = "${AWS_ACCOUNT_ID}..."中赋值号两边不能有空格,Shell要求变量赋值必须是变量名=值的格式,不能存在空格。 - 变量引用错误:
${$VERSION}多了一个美元符号,正确写法为${VERSION}。
除此之外,原代码还有几个可优化的问题:
IMAGE_REPO_NAME包含了tag(testio:latest),导致后续tag操作逻辑混乱,应将仓库名和tag分开定义。- Jenkins环境变量在单引号包裹的
sh脚本块中无法被解析,需要调整引号使用方式。 - 解析
build.gradle文件获取版本号的方式不够可靠,容易因文件格式变动失效。
修复并简化后的流水线代码
pipeline { agent any environment { AWS_ACCOUNT_ID = "123456789" AWS_DEFAULT_REGION = "us-east-1" IMAGE_REPO_NAME = "testio" // 仅保留仓库名,tag单独定义 IMAGE_TAG_LATEST = "latest" JENKINS_GIT_CREDS = "8f6bc3ab-9ef5-4d89-8e14-4972d63325c5" AWS_ECR_CREDS = "ecr:us-east-1:aws-credentials" } stages { stage('拉取代码') { steps { git credentialsId: "${JENKINS_GIT_CREDS}", url: 'http://192.168.1.7:7990/scm/jen/spring-boot-microservice.git', branch: 'master' } } stage('构建应用与Docker镜像') { steps { sh 'chmod +x gradlew && ./gradlew clean build --no-daemon' // 用Gradle命令直接提取版本号,避免解析文件出错 script { APP_VERSION = sh(script: './gradlew properties -q | grep "version:" | awk \'{print $2}\'', returnStdout: true).trim() env.APP_VERSION = APP_VERSION } // 一次构建同时打latest和版本号两个标签 sh "docker build -t ${IMAGE_REPO_NAME}:${IMAGE_TAG_LATEST} -t ${IMAGE_REPO_NAME}:${APP_VERSION} ." } } stage('推送镜像到AWS ECR') { steps { script { def ecrRegistry = "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com" docker.withRegistry("https://${ecrRegistry}", "${AWS_ECR_CREDS}") { // 推送latest标签镜像 docker.image("${IMAGE_REPO_NAME}:${IMAGE_TAG_LATEST}").push() // 推送版本号标签镜像 docker.image("${IMAGE_REPO_NAME}:${APP_VERSION}").push() } } } } } }
关键优化点说明
- 变量拆分:将仓库名与tag分离,避免后续tag操作逻辑混乱。
- 可靠版本获取:用
./gradlew properties命令直接提取版本号,比解析build.gradle文件更稳定,不受文件格式变动影响。 - 简化Docker操作:利用Jenkins Docker插件的
push()方法,省去手动执行docker tag和docker push的重复命令。 - 环境变量清晰化:将Git凭证、AWS ECR凭证单独定义,便于后续维护修改。
- 引号规范:使用双引号包裹
sh命令,确保Jenkins环境变量能被正确解析。
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

