• Home
  • LLMs
  • Docker
  • Kubernetes
  • Java
  • Ubuntu
  • Maven
  • Archived
  • About
Docker | Build Docker images (docker build)
  1. Notes
  2. Build an image (docker build)
  3. Build cache
  4. Multi-stage builds
  5. Debug a failing build

  1. Notes
    See these pages for more information:
    Docker CLI: docker build (build an image from a Dockerfile)
    https://docs.docker.com/reference/cli/docker/buildx/build/
    https://docs.docker.com/build/building/multi-stage/

    Docker introduced new backend for builing images (buildkit) which doesn't expose intermediate containers.
    To show intermediate containers, set the environment variable DOCKER_BUILDKIT before the docker build command:
  2. Build an image (docker build)
    The 'docker build' command has the following syntax:

    Note that docker image build is equivalent to docker build

    Let's use this Dockerfile:

    To build an image from a Dockerfile:

    The option '-t IMAGE_NAME:IMAGE_TAG' instruct Docker to create an image with the specified name (ubuntu-nginx) and tag (20.04).

    The character '.' at the end of the docker build command specifies the current directory. You can specify any path you want. It represents the path where Docker looks for all files and directories managed in the Dockerfile.

    By default, Docker will look for a Dockerfile with the name 'Dockerfile' in the current directory. You can use the '-f' option to specify an alternate location and a custom Dockerfile name.

    You can add a ".dockerignore" file where you can list files and directories that you want to be excluded when building the image. Therefore, these files and directories are not sent to the builder, which can help improve build speed (especially when using a remote Docker host).

    The build command produces the following output:

    In this case it's the first time the image is built. All the steps are executed and no cache was used by Docker.

    To list the images (the one we created "ubuntu-nginx" + the parent image "ubuntu"):
  3. Build cache
    Steps in the Dockerfile that produces image layers are cached and can be used by Docker when rebuilding the image which can reduces significantly the build time.

    Let's execute again the build command. The output should be similar to the following:

    As you can see, Docker verify for each build step if there is a cached layer, and if it does exists, it will use it (see ---> Using cache).

    Let's change the Dockerfile a bit (I will change the group id and user id):

    Let's execute the build command. The output should be similar to the following:

    As you can notice, the instruction of the step 2 was changed and hence Docker is building a new image layer. Docker will then execute the subsequent steps and won't use the local cache even if the remaining steps didn't change at all.
  4. Multi-stage builds
    Multi-stage builds feature allow you to add multiple FROM instructions in the Dockerfile. The FROM instructions are basicaly the same as the regular single FROM instructions that we have used previously. Each FROM instruction define a build stage that has its base image and a set of instructions to build images layers. A FROM instruction should have a name which can be used by other FROM instructions as a reference. The FROM instruction that references another one, will be able to copy artifacts created within that staging build.

    A staging build can be considered as a temporary build that we can use in the next staging builds to copy only the artifacts that we need and discards everything else. The goal is to have an optimized final stage (in term of disk space) that in theory will be the one that we will use for the image we want to create.

    Let's use this Dokerfile (not a very useful one but it's simple enough to demonstrate the multi-stage builds feature):

    Let's build the Dockerfile:

    Let's have a look at the image history:

    As you can see, the image does contain only the layers of the base image (alpine) and the layer of the COPY instruction.

    Notes:
    • Assigning a name to a stage build is recommended but not mandatory. Instead of using the name of the stage build you can reference it by its number. The first FROM instruction in the Dockerfile has the number 0 and the following will be numbered 1,2,3, and so on. To reference the first build stage, you do: COPY --from=0 ...

    • It's also possible to copy artifacts from external images (kind of using the image as a stage):

    • You can also use a stage build as a base image for the FROM instruction (FROM stage0 AS stage1):
  5. Debug a failing build
    Let's use this Dockerfile above (notice the typo with the useradd command):

    Let's build the Dockerfile:

    In this case we can see the build complains about the command 'userad'.

    In some cases the error might not be very clear from the build output, so a nice feature in Docker is that you can use an intermediate layer of the image to start a container and debug any failing command.

    For example, we can run a container from the created layer '1e4467b07108' (see above) and execute commands directly in the container:
© 2025  mtitek