How do I run a CI build in a docker image matching the current Dockerfile while being resource-aware?

HOW TO -️ October 18, 2021

Given a repository containing a Dockerfile that defines the build environment used by the CI pipeline as well as by the developer (e.g. as a Visual Studio Code devcontainer), the CI pipeline shall fulfill the following requirements:

  1. The CI pipeline shall build the repository's contents in the context of a docker image built from the very Dockerfile present in the working branch (or the result of its merge to the target branch where applicable in the context of a pull request).
  • Rationale: Builds shall be deterministic so that old repository versions shall be built with their original docker image, not with the newest one.
  • Rationale: Changes to the Dockerfile shall be considered automatically without the need for manual user intervention (i.e. local docker build followed by a manual push).
  1. The CI pipeline shall reuse an already built docker image if the applicable Dockerfile has already been "baked" into such an image pushed to the registry.
  • Rationale: Building a docker image on each commit is resource-consuming (time, energy).

I couldn't find an existing best practice to implement that out of the box (my CI environment being Azure DevOps Pipelines if it matters) so I came with the following concept:

  • Calculate the Dockerfile's hash.
  • Load docker_image_name:$hash from the docker registry.
  • If the load fails, build docker_image_name:$hash from the Dockerfile and push it to the docker registry.
  • Use docker_image_name:$hash (from the registry / from the local cache) to run the CI pipeline (using Azure's container jobs in my case).


  1. Does this procedure make sense as a solution to my use case?
  2. I can't imagine being the first to realize this use case. Is there an existing mechanism (as part of the docker utilities, as part of the Azure DevOps Pipelines framework or from something completely different) that fulfills my needs?


I wasn't exactly sure if you was asking how to use a vscode dev container in a azure pipeline or if you was asking how to replicate that dev container functionality from scratch. @Levi: My mentioning vscode's devcontainers might have been misleading since it was just part of the context, but not part of the actual question. The question was specifically about how to use the very docker image specified by the currently valid Dockerfile without building the image on each and every commit. I think the question boils down to "How do I avoid rebuilding my container image in CICD" which probably has been asked and answered before. I went ahead and gave a new answer though.