I am having trouble with a docker deployment to Azure Container Registry (ACR). My goal is to build my docker image once, and deploy it over 4 environments (dev, test, acc, prd). The reason I want to only build the docker image once is that the docker build process takes about 1 hour, which I would rather not repeat 4 times
My question is: How can I do this within azure devops without having to define the "containerRegistry" in the build task?
The problem I run into is that I have to specify a containerRegistry variable when building using the Docker@2 build task. Else the Docker@2 push step will fail with an error like:
An image does not exist locally with the tag: ***.azurecr.io/repository_name
I do not want to specify this value in the build process, because each environment has its own container registry. So specifying this would still require me to create a build for each individual environment.
Build step
- 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"
Push step (in another stage)
- 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"
So as it turns out this is possible by manually retagging the docker build before pushing it, as described in the link below:
https://dev.to/n3wt0n/container-image-promotion-across-environments-build-artifact-5887
Summary: After building the image I had to save the image as a .TAR file, after which I could publish it as an Artifact:
- 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"
Then in a different stage I could collect the stored artifact, load the .tar file and by manually retagging it through the docker@2 step I was able to make the build accessible for pushing it.
# 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"