How to use docker buildx history trace to view build traces

DockerDockerBeginner
Practice Now

Introduction

In this lab, you will learn how to use docker buildx history trace to view and analyze the build traces of your Docker images. You will begin by building a simple Docker image and recording its build history using standard Docker commands.

Following the initial build, you will explore how to list the recorded build history records and then delve into viewing the detailed OpenTelemetry trace of a specific build record. Finally, you will learn how to compare the traces of two different build records, providing valuable insights into the build process and potential optimizations.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") docker/ImageOperationsGroup -.-> docker/images("List Images") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/inspect -.-> lab-555056{{"How to use docker buildx history trace to view build traces"}} docker/images -.-> lab-555056{{"How to use docker buildx history trace to view build traces"}} docker/build -.-> lab-555056{{"How to use docker buildx history trace to view build traces"}} end

Build an image and record its history

In this step, you will learn how to build a Docker image and record its build history. Docker images are built from a Dockerfile, which is a text file that contains all the commands a user could call on the command line to assemble an image.

First, let's create a simple Dockerfile. Navigate to the ~/project directory if you are not already there.

cd ~/project

Now, create a file named Dockerfile using the nano editor.

nano Dockerfile

Add the following content to the Dockerfile:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y --no-install-recommends fortune-mod
CMD ["/usr/games/fortune"]

This Dockerfile starts from the latest Ubuntu image, updates the package list, installs the fortune-mod package, and sets the default command to run the fortune program.

Save the file and exit nano (Press Ctrl + X, then Y, then Enter).

Now, let's build the Docker image using the docker build command. We will tag the image as my-fortune-image and use the current directory (.) as the build context.

docker build -t my-fortune-image .

You will see output indicating the build process, including downloading the base image and running the apt-get command.

To record the build history, we can use the docker history command. This command shows the history of an image.

docker history my-fortune-image

The output will show a list of layers that make up the image, along with the command used to create each layer, the size of the layer, and when it was created. This history is useful for understanding how an image was built and for debugging.

List build history records

In this step, you will learn more about listing the build history records of a Docker image. As you saw in the previous step, the docker history command provides a detailed view of the layers that make up an image.

Let's run the docker history command again for the my-fortune-image we built in the previous step.

docker history my-fortune-image

The output displays several columns:

  • IMAGE: The ID of the image layer.
  • CREATED: The timestamp when the layer was created.
  • CREATED BY: The command that created the layer.
  • SIZE: The size of the layer.
  • COMMENT: Any comment associated with the layer.

Each line in the output represents a layer in the image. The layers are listed from the most recent (top) to the oldest (bottom). The base image (ubuntu:latest in our case) is the bottom layer.

You can also use the -q flag to only show the image IDs.

docker history -q my-fortune-image

This can be useful if you only need the layer IDs for scripting or other purposes.

The docker history command is a powerful tool for understanding the composition of a Docker image and for debugging issues related to image layers.

View the OpenTelemetry trace of a build record

In this step, you will learn how to view the OpenTelemetry trace of a Docker build record. OpenTelemetry is a collection of tools, APIs, and SDKs used to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software's performance and behavior. Docker can integrate with OpenTelemetry to provide detailed traces of the build process.

To view the OpenTelemetry trace, you need to enable tracing when building the image. We will rebuild the my-fortune-image with tracing enabled.

First, ensure you are in the ~/project directory.

cd ~/project

Now, build the image again, but this time, we will set the BUILDKIT_TRACE environment variable to enable tracing. We will also use the --progress=plain flag to see the build output directly.

BUILDKIT_TRACE=trace.json docker build --progress=plain -t my-fortune-image .

This command will rebuild the image and save the OpenTelemetry trace data to a file named trace.json in the current directory.

After the build completes, you can view the contents of the trace.json file. This file contains the trace data in JSON format.

cat trace.json

The output will be a large JSON object containing detailed information about the build process, including the duration of each step, dependencies, and other metadata. This trace data can be imported into an OpenTelemetry-compatible tracing backend (like Jaeger or Zipkin) for visualization and analysis.

While we won't be setting up a full tracing backend in this lab, understanding how to generate the trace file is the first step in leveraging OpenTelemetry for Docker build analysis.

Compare traces of two build records

In this step, you will learn how to generate and compare OpenTelemetry traces from two different Docker build records. Comparing traces can be useful for identifying performance differences between builds, especially after making changes to your Dockerfile or build environment.

First, ensure you are in the ~/project directory.

cd ~/project

We already have a trace.json file from the previous build. Let's rename it to trace1.json to keep it.

mv trace.json trace1.json

Now, let's make a small change to our Dockerfile and build the image again, generating a second trace file. We will add a simple LABEL instruction to the Dockerfile.

Open the Dockerfile for editing.

nano Dockerfile

Add the following line after the CMD instruction:

LABEL version="1.0"

The updated Dockerfile should look like this:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y --no-install-recommends fortune-mod
CMD ["/usr/games/fortune"]
LABEL version="1.0"

Save the file and exit nano.

Now, build the image again, generating a new trace file named trace2.json.

BUILDKIT_TRACE=trace2.json docker build --progress=plain -t my-fortune-image .

After the build completes, you will have two trace files: trace1.json and trace2.json.

While directly comparing the raw JSON files can be challenging, these files are designed to be consumed by OpenTelemetry tracing backends. In a real-world scenario, you would import both trace1.json and trace2.json into a tracing visualization tool (like Jaeger). This tool would allow you to visually compare the timelines and spans of the two builds, making it easy to spot differences in execution time and identify which steps were affected by your changes.

For example, if you were to view these traces in Jaeger, you would see the individual steps of the Docker build (like FROM, RUN, CMD, LABEL) as spans. You could then compare the duration of these spans between the two traces to see if adding the LABEL instruction had any measurable impact on the build time.

Since we don't have a tracing backend set up in this lab, we will simply verify that both trace files exist.

Summary

In this lab, you learned how to build a Docker image from a Dockerfile using the docker build command, tagging the image for easy identification. You then explored how to view the build history of the created image using the docker history command, which provides insights into the layers and commands used during the build process.

The lab further guided you on listing build history records in more detail, demonstrating the information available through the docker history command. You also learned how to view the OpenTelemetry trace of a specific build record, allowing for deeper analysis of the build process. Finally, you practiced comparing the traces of two different build records, which is useful for understanding changes and debugging build issues.