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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:48:15