在 Devops docker 构建任务中不定义容器注册表而单独构建和推送

Seperate build and push without defining containerRegistry in Devops docker build task

我在 docker 部署到 Azure 容器注册表 (ACR) 时遇到问题。 我的目标是一次构建我的 docker 映像,然后将其部署到 4 个环境(开发、测试、acc、prd)。 我只想构建一次 docker 图像的原因是 docker 构建过程大约需要 1 小时,我不想重复 4 次

我的问题是:如何在 azure devops 中执行此操作而不必在构建任务中定义“containerRegistry”?

我 运行 遇到的问题是,在使用 Docker@2 构建任务进行构建时,我必须指定一个 containerRegistry 变量。否则 Docker@2 推送步骤将失败并出现如下错误:

An image does not exist locally with the tag: ***.azurecr.io/repository_name

我不想在构建过程中指定这个值,因为每个环境都有自己的容器注册表。所以指定这个仍然需要我为每个单独的环境创建一个构建。

构建步骤

- task:                                       Docker@2
  inputs:
    repository:                              "${{ parameters.dockerImgName }}"
    command:                                  build
    Dockerfile:                              "${{ parameters.dockerBuildDockerfile }}"
    tags: |                                  
                                              ${{ parameters.dockerImageTag }}
                                              latest
    buildContext:                            "${{ parameters.dockerBuildContext }}"
    containerRegistry:                        ${{ parameters.containerRegistry}}**
  displayName:                               "Build the image"

推步(在另一个阶段)

- task:                                       Docker@2
  inputs:
    repository:                              "${{ parameters.dockerImgName }}"
    command:                                  push
    Dockerfile:                              "${{ parameters.dockerBuildDockerfile }}"
    tags:                                    "latest"
    buildContext:                            "${{ parameters.dockerBuildContext }}" 
    containerRegistry:                        ${{ parameters.acrConnection }}
  displayName:                               "Push the image with latest tag"

事实证明,这可以通过在推送之前手动重新标记 docker 构建来实现,如下面的 link 所述:

https://dev.to/n3wt0n/container-image-promotion-across-environments-build-artifact-5887

总结: 构建图像后,我必须将图像保存为 .TAR 文件,之后我可以将其发布为工件:

- task:                                       Docker@2
  inputs:
    command:                                 "save"
    arguments:                               "--output $(Build.ArtifactStagingDirectory)/${{ parameters.dockerImgName }}.image.tar ${{ parameters.dockerImgName }}:${{ parameters.dockerImageTag }}"
    displayName:                             "Save the image as a .tar"

- task:                                       PublishBuildArtifacts@1
  inputs:
    PathtoPublish:                           "$(Build.ArtifactStagingDirectory)"
    ArtifactName:                            "drop"
    publishLocation:                         "Container"
    displayName:                             "Publish image as an artifact"                      "Save the image as a .tar"

然后在不同的阶段我可以收集存储的工件,加载 .tar 文件并通过 docker@2 步骤手动重新标记它我能够使构建可访问推动它。

    # collect the docker artifact from azure devops
- task:                                       DownloadBuildArtifacts@1
  displayName:                               "Collect docker artifact"
  inputs:
    buildType:                               "current"
    downloadType:                            "single"
    artifactName:                            "drop"
    downloadPath:                            "$(System.ArtifactsDirectory)"

- task:                                       Docker@2
  inputs:
    command:                                 "load"
    arguments:                               "--input $(System.ArtifactsDirectory)/drop/${{ parameters.dockerImgName }}.image.tar"

- task:                                       Docker@2
  inputs:
    command:                                 "tag"
    containerRegistry:                        ${{ parameters.acrConnection }}
    arguments:                               "${{ parameters.dockerImgName }}:${{ parameters.dockerImageTag }} ${{parameters.acrName}}.azurecr.io/${{ parameters.dockerImgName }}:${{ parameters.dockerImageTag }}"

- task:                                       Docker@2
  inputs:
    repository:                              "${{ parameters.dockerImgName }}"
    command:                                  push
    Dockerfile:                              "${{ parameters.dockerBuildDockerfile }}"
    tags:                                    "${{ parameters.dockerImageTag }}"
    buildContext:                            "${{ parameters.dockerBuildContext }}" 
    containerRegistry:                        ${{ parameters.acrConnection }}
  displayName:                               "Push the image with id tag"