Where’s that log file? Debugging failed Docker builds

You’ve got a nice new Dockerfile, and it’s time to try it out:

$ docker build -t mynewimage .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM python:3.8-slim-buster
 ---> 3d8f801fc3db
Step 2/3 : COPY build.sh .
 ---> 541b65a7b417
Step 3/3 : RUN ./build.sh
 ---> Running in 9917e3865f96
Building...
Building some more...
Build failed, see /tmp/builderr024321.log for details
The command '/bin/sh -c ./build.sh' returned a non-zero code: 1

So—now what? That log file isn’t on your host computer’s filesystem, it’s in the temporary image that build was creating.

How do you read that log file? Let’s find out.

Debugging the build

That log file isn’t on your host computer’s filesystem, it’s in the temporary image that build was creating. In some versions of Docker you can access this temporary image, but not in the new and mostly-improved BuildKit build system. So we’re going to take a different approach.

Specifically, what we’re going to do is rebuild the image, disabling the failed line and all lines after it. Our Dockerfile currently looks like this:

FROM python:3.8-slim-buster
COPY build.sh .
RUN chmod +x build.sh
RUN ./build.sh

You want to make sure changes to Dockerfile don’t impact layer caching; you can do so by having a .dockerignore that includes the Dockerfile. In the case of our example, we’re only COPYing in build.sh so changes to Dockerfile won’t invalidate the cache.

We comment out the failed line, and the Dockerfile now looks like this:

FROM python:3.8-slim-buster
COPY build.sh .
RUN chmod +x build.sh
#RUN ./build.sh

We can now rebuild the image:

$ docker build -t mynewimage .
...
Successfully built 7759cef14db8
Successfully tagged mynewimage:latest

Now we can run the image, and then manually run the failing step, and since we’re inside the container we can also access the resulting log file:

$ docker run -it mynewimage /bin/bash
root@c6060c04282d:/# ./build.sh 
Build failed, see /tmp/builderr024321.log for details
root@c6060c04282d:/# cat /tmp/builderr024321.log 
ONO MISSING FLUX CAPACITOR
root@c6060c04282d:/# 

And now we know the problem: apparently there’s a missing flux capacitor.

Once we’ve fixed the problem, we can uncommit the last line(s) of the Dockerfile and continue with the build.

Just Enough Docker PackagingWant to quickly get up to speed on Docker packaging? This article is based on my book, Just Enough Docker Packaging, which will help teach you the basics of Docker packaging in just one afternoon.