Capture ouput of docker build into a log file?

I’d like to be able to capture the output of a docker build task into a log file.

I assumed that docker build <arguments> --progress=plain >> docker-build.log would suffice however the resulting file is empty.

I’ve tried to see if docker keeps a log file anywhere of the output from builds however I’ve not been able to find any reference to this.

That’s because the output is not on the standard output but the standard error stream. So you can try this to redirect everything into the file:

docker build --no-cache --progress=plain  . &> build.log

or just redirect standard error if you think there should be some other output to show in the terminal

docker build --no-cache --progress=plain  . 2> build.log

Or you can use tee to show the logs and also save it to a file

docker build --no-cache --progress=plain . 2>&1 | tee build.log

If you want to append new logs and not to overwrite on every build, use >> for the redirection as you did originally. If you choose the version with tee, you can use tee -a to append the new logs

7 Likes

That worked perfectly.

Thank you!

I am glad it helped.

When I came back to see your response I noticed I left the --no-cache option in all of my commands. That option is not required of course. You can remove it.

Is there extra magic that you need to do on a Mac? I ran

docker build \
       -t my-image:latest \
       -f docker/Dockerfile \
       --build-arg SOME_ARG=value \
       --target sometarget \
       --progress=plain \
       .

inside a script, and launched the script as

my-script.sh 2>&1 > build.log

but build.log was empty when I was done

1 Like

No magic on Mac. I had three examples, but none of those are what you tried.

As you can see I used the tee command after a pipe character (|).

What you did just redirected the error stream to the standard output and did nothing with it, and also independently redirected the standard output (which was empty) to build.log. To give you an example to test what happened, create the following script as output.sh

>&1 echo "stdout"
>&2 echo "stderr"

Make it executable:

chmod +x output.sh

and run the following command:

my-cript.sh > out1.log > out2.log

It will just redirect the standard output to two different log files. This is the same as the following command:

my-cript.sh 1> out1.log 1> out2.log

You could redirect the error logs multiple times too

my-cript.sh 1> out1.log 1> out2.log 2> err1.log 2> err2.log

Then run the following command to get the stderr and stdout two times

cat *.log
stderr
stderr
stdout
stdout

So these redirections are not chained, but independent.

If you don’t like the tee command, your solution could work with parenthesis:

(my-script.sh 2>&1) > build.log

This way my-script.sh 2>&1 would run first and the result would be redirected to the build log. I think it would just complicate things as my first original example would redirect everything the same way without parenthesis and without the tee command.

In your case:

my-script.sh &> build.log

Notice the & character instead of 1 or 2.

1 Like