409

Snippet from my Dockerfile:

FROM node:12.18.0
RUN echo "hello world"
RUN psql --version

When I run docker build . I don't see any output from these two commands even if they are not cached. The documentation says that docker build is verbose by default. Why am I not seeing the output from commands? I used to see them before.

The output while building:

=> [7/18] RUN echo "hello world"                         0.9s

The output I am seeing after building finishes:

=> CACHED [6/18] RUN apt-get install postgresql -y      0.0s
=> [7/18] RUN echo "hello world"                        6.4s
=> [8/18] RUN psql --version                           17.1s

The Dockerfile is created from node:12.18.0 which is based on Debian 9.

Docker version 19.03.13, build 4484c46d9d.

Ash Singh
  • 3,921
  • 2
  • 25
  • 30
Noname
  • 4,432
  • 2
  • 10
  • 17

6 Answers6

559

The output you are showing is from buildkit, which is a replacement for the classic build engine that docker ships with. You can adjust output from this with the --progress option:

  --progress string         Set type of progress output (auto, plain, tty). Use plain to show container output
                            (default "auto")

Adding --progress=plain will show the output of the run commands that were not loaded from the cache. This can also be done by setting the BUILDKIT_PROGRESS variable:

export BUILDKIT_PROGRESS=plain

If you are debugging a build, and the steps have already been cached, add --no-cache to your build to rerun the steps and redisplay the output:

docker build --progress=plain --no-cache ...

If you don't want to use buildkit, you can revert to the older build engine by exporting DOCKER_BUILDKIT=0 in your shell, e.g.:

DOCKER_BUILDKIT=0 docker build ...

or

export DOCKER_BUILDKIT=0
docker build ...
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • 54
    The answer regarding `--progress=plain` does not appear to work anymore. On OS X for me, it merely spits out the command, hash, and step result (e.g. "CACHED"). Only forcibly disabling buildkit returns any useful output now. Is this a recent change, or different depending on platform? – Neo Jun 21 '21 at 20:20
  • 11
    @Jon if the step is cached, no command is run, so there's no output to show. It's the same with or without buildkit. – BMitch Jun 21 '21 at 20:48
  • 44
    use `docker build --progress=plain --no-cache ...` to disable caching and print all output – piouson Sep 06 '21 at 08:15
  • I would not recommend disabling build kit. – ruohola Oct 05 '21 at 12:55
  • @ruohola neither would I. That's why I push for `--progress=plain`. But some people just want things the old way no matter what advice you give. – BMitch Oct 05 '21 at 14:01
  • 11
    I'd like to know who in their right mind at Docker decided to hide the caching hashes by default. "Hey we're going to break every Docker debug tutorial on the planet, lets go for it!". They gave a big ol' middle finger to the dev community IMO. – Justin Fortier Jan 14 '22 at 17:42
  • 6
    Unfortunately it doesn't seem to work for me. – Filip Górny Jan 21 '22 at 10:15
  • 1
    Have to side with @JustinFortier. I am currently trying to examine the contents of an image that fails to build completely, but neither `plain`, nor `tty` gives me any usable output, which is not great. – znovotny Sep 01 '22 at 14:49
  • 1
    `--no-cache` appears to have no effect. All the commands are still `CACHED`. – Grant Birchmeier Jan 12 '23 at 19:43
  • If it doesn't work for you, please post a new question with a [mcve] or a separate answer with what does work if it's different from the answers here. – BMitch Jan 12 '23 at 19:52
  • I used this command and logged it to file and observed that the entire output is logged to stderr (for whatever reason). So use `docker build -f Dockerfile --no-cache --progress=plain . |& tee build_output.txt` if you are vintage and want to have the output in a file or if you do not have access to stdout. – h0ch5tr4355 Feb 24 '23 at 12:54
130

Just use this flag --progress=plain after build.

For example:

docker-compose build --progress=plain <container_name>

OR

docker build --progress=plain .

If you don't want to use this flag every time, then permanently tell docker to use this flag by doing:

export BUILDKIT_PROGRESS=plain

Here is the official documentation when you type docker build --help.

--progress string         Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
Ash Singh
  • 3,921
  • 2
  • 25
  • 30
  • You might need to clear your docker build cache to see output instead of the hash from the previous build. A brute force way to do that is `docker system prune` – Leo Jan 07 '22 at 18:21
  • 1
    Does not work with docker-compose, `unknown flag: --progress` – Peter Kionga-Kamau Apr 19 '22 at 22:00
  • It works for me, which version of docker-compose are you on ? `docker-compose -v` @PeterKionga-Kamau – Ash Singh Apr 20 '22 at 10:52
  • @PeterKionga-Kamau Have you ensured to use `--progress` after `docker-compose build` not before, as mentioned in the answer ? – Ash Singh Apr 20 '22 at 10:55
  • 1
    @AshSingh yes of course. `docker-compose -p output-test -f docker-compose.custom.yml --verbose up -d --build --progress=plain` – Peter Kionga-Kamau Apr 20 '22 at 21:51
  • @PeterKionga-Kamau You are using `docker-compose up` command not `docker-compose build`. This question is about docker build not about running the container. – Ash Singh Apr 21 '22 at 03:52
  • 1
    @AshSingh aha! ty ty. very true. This explains some of the issues we've been having with options order too. – Peter Kionga-Kamau Apr 21 '22 at 21:38
  • How to set `export BUILDKIT_PROGRESS=plain` on Windows? I am using PowerShell. – krave Oct 10 '22 at 06:30
37

In Docker 20.10 i had to use the --no-cache flag, too. Otherwise cached output is not shown.

docker build --progress=plain --no-cache .
volkit
  • 1,173
  • 14
  • 21
  • 14
    `--no-cache` doesn't just hide the cached output, it disables Docker's layer caching completely. You certainly don't want to use that all the time. – ruohola Oct 18 '21 at 10:07
  • Yes, one thing has nothing to do with the other. Docker by default caches build steps. When you change a line and build again, every subsequent line will be built again by default, because there's no need to repeat existing steps, they're already cached. – itmuckel Apr 25 '22 at 17:18
  • 2
    I used `--no-cache` but I still see `CACHED` on the commands :/ – Grant Birchmeier Jan 12 '23 at 19:48
29

As an alternative to specifying the --progress=plain option, you can also permanently disable the "pretty" output by setting this env variable in your shell config:

export BUILDKIT_PROGRESS=plain
ruohola
  • 21,987
  • 6
  • 62
  • 97
28

Do 2 things

  1. Instead of docker build . use this
docker build . --progress=plain
  1. Add random junk to your RUN command every build (this tricks docker into thinking it hasn't seen the command before, so it doesn't use the cached version)

Example. If your command is RUN ls use this instead RUN ls && echo sdfjskdflsjdf (change the sdfjskdflsjdf to something else each time you build).

Why this works

I tried other answers and they all presented problems and imperfections. It's highly frustrating that Docker doesn't have some simple functionality like --verbose=true.

Here's what I ended up using (it's ludicrous but it works).

Suppose you want to see the output of ls command, this won't work docker build .

RUN ls

but this will print the output docker build --progress=plain:

RUN ls

now try again, it won't print! - that's because docker caches the unchanged layer, so the trick is to alter the command each time by adding some nonsense to it && echo sdfljsdfljksdfljk, and changing the nonsense each time docker build --progress=plain:

# This prints
RUN ls && echo sdfljsdfljksdfljk
# Next time you run it use a different token
RUN ls && echo sdlfkjsldfkjlskj

So each and every time, I mash the keyboard and come up with a new token. Stupifying. (note that I tried something like && openssl rand -base64 12 to generate a random string, but docker realises the code hasn't changed that doesn't work).

This solution is highly inferior to genuine docker support for printing output to console.

stevec
  • 41,291
  • 27
  • 223
  • 311
  • 1
    Just no. Use `ARG` Dockerfile statements and then in your `RUN` statement, do `&& echo $ARG_NAME`. At build time, do `--build-arg ARG_NAME=$(date)`. Any command referencing an ARG that has changed will have its layer invalidated. – ErikE Dec 07 '22 at 02:24
  • @ErikE that's a nice idea. I'll try it when I get a chance, update the answer to reflect it, and credit you – stevec Dec 07 '22 at 02:31
  • 1
    Just be aware that if you use build stages, you must have an `ARG` before the first `FROM` and then another `ARG` inside each `FROM` stage that you want to use the `ARG` in. You can make `ARG` values non-required by setting a default value, allowing you to cache-bust any time you want, or not. Oh, and you don't even need to put the arg usage in a layer. Just put it in the statement before, such as `ENV SOMETHING=$ARG_NAME` which will invalidate all subsequent layers. – ErikE Dec 07 '22 at 02:34
  • Cool. I haven't used `ARG` before so I don't understand just from hearing the suggestion, but I'm sure it will make sense to me when I try it. Thanks again – stevec Dec 07 '22 at 02:35
  • 3
    `ARG LS_VERSION=none; FROM imagename AS install; ARG LS_VERSION; RUN echo $LS_VERSION; RUN ls` (converting semicolons to newlines). Now you can `docker build` and `LS_VERSION` will be set to `none`, or you can `docker build --build-arg LS_VERSION=1` and cache-bust (or `date` or whatever you like). – ErikE Dec 07 '22 at 02:37
0

If your error looks something like this:

#7 0.584 /bin/sh: 1: /install.sh: not found

it's telling you the error is in line number 1. you are running into windows line endings

I was using VS code and I solved it pretty easily by converting the file from CRLF to LF using VS code.

just click on the CRLF button in the bottom right corner of the editor and save the file.

everything should work fine when you build the image now.

Rahat
  • 111
  • 3
  • 5