如何利用变更检测脚本输出为特定应用执行CI/CD Docker构建
问题描述
我仓库里有3个不同的应用,正在搭建CI/CD流水线来构建Docker镜像并推送到ECR仓库。流水线分为两个阶段:
- Affected阶段:通过
npx nx print-affected命令检测有变更的项目,把输出保存到制品文件apps.txt,用来定位需要构建的项目目录。 - Build阶段:依赖Affected阶段的输出,现在已经能读取
apps.txt的内容,但不知道怎么用这个输出来构建对应应用的Docker镜像。
当前流水线配置如下:
stages: - affected - build .distributed: interruptible: true only: - main affected: image: node:18 stage: affected cache: key: files: - package-lock.json paths: - .npm/ extends: .distributed before_script: - npm ci --cache .npm --prefer-offline - NX_HEAD=$CI_COMMIT_SHA - NX_BASE=${CI_MERGE_REQUEST_DIFF_BASE_SHA:-$CI_COMMIT_BEFORE_SHA} script: - echo "$(npx nx print-affected --type=app --select=projects --base=$NX_BASE --head=$NX_HEAD)" > apps.txt artifacts: paths: - apps.txt - node_modules/.cache/nx build: stage: build dependencies: - affected image: name: gcr.io/kaniko-project/executor:debug entrypoint: [""] script: - mkdir -p /kaniko/.docker - echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json - for APP in $(cat apps.txt); do echo $APP; done - echo ${CI_PROJECT_DIR} # - /kaniko/executor # --context "." # --dockerfile "${CI_PROJECT_DIR}/Dockerfile" # --destination "$ECR_REPO_CURRENT:${CI_COMMIT_TAG}"
解决方案
要根据apps.txt里的项目逐个构建Docker镜像,只需调整Build阶段的脚本,针对每个应用执行Kaniko构建命令即可。以下是适配后的配置(假设每个应用的Dockerfile存放在apps/${APP}目录下,你可以根据实际目录结构修改路径):
build: stage: build dependencies: - affected image: name: gcr.io/kaniko-project/executor:debug entrypoint: [""] script: - mkdir -p /kaniko/.docker - echo "{\"credsStore\":\"ecr-login\"}" > /kaniko/.docker/config.json # 遍历apps.txt中的每个应用 - for APP in $(cat apps.txt); do # 替换为你的ECR仓库前缀,比如123456789012.dkr.ecr.us-east-1.amazonaws.com/${APP} ECR_DESTINATION="你的ECR仓库前缀/${APP}:${CI_COMMIT_SHA}"; echo "开始构建应用: ${APP},推送镜像至: ${ECR_DESTINATION}"; /kaniko/executor \ --context "${CI_PROJECT_DIR}/apps/${APP}" \ --dockerfile "${CI_PROJECT_DIR}/apps/${APP}/Dockerfile" \ --destination "${ECR_DESTINATION}"; done
关键细节说明
- 路径适配:如果你的应用结构不同(比如Dockerfile在根目录但需要传递应用专属构建参数),可以修改
--context和--dockerfile的路径,或者添加--build-arg参数传递变量。 - 镜像标签:用
CI_COMMIT_SHA作为标签能保证每个构建版本唯一,也可以根据需求替换成CI_COMMIT_TAG或分支名。 - 空场景处理:如果
apps.txt为空(无变更应用),循环会自动跳过,不会执行无用的构建操作。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

