moby / buildkit

concurrent, cache-efficient, and Dockerfile-agnostic builder toolkit
https://github.com/moby/moby/issues/34227
Apache License 2.0
8.08k stars 1.13k forks source link

docker build command outputs general information lines to stderr instead of stdout when buildKit is enabled. #1186

Open pratiksanglikar opened 4 years ago

pratiksanglikar commented 4 years ago

Description

docker build commands output general information lines to standard error instead of standard output when buildKit is enabled.

This is particularly problematic for extra tooling we have around docker which depend on lines on stderror to determine if the command was successful.

Following is the output of docker build command which is returned on the stderr instead of stdout. The process has exitcode=0 so, it shouldn't ideally put these lines on stderr.

Steps to reproduce the issue:

  1. Make sure to have Docker version >= 19.03
  2. Enable BuildKit by setting environment variable - DOCKER_BUILDKIT=1
  3. Run docker build command on any project.
  4. Verify the output of the command is on stderr instead of stdout.

Describe the results you received: General information lines are present on stderr.

#2 [internal] load .dockerignore
#2 transferring context: 35B done
#2 DONE 0.1s

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 32B done
#1 DONE 0.1s

#3 [internal] load metadata for mcr.microsoft.com/dotnet/core/aspnet:3.0-bu...
#3 DONE 0.1s

#4 [base 1/2] FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim@sha...
#4 resolve mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim@sha256:b0fd451ed5dcd9c86a5c5364b478ebfb411beada0740369127fa53bca365650f done
#4 DONE 0.0s

#5 [base 2/2] WORKDIR /app
#5 CACHED

#6 exporting to image
#6 exporting layers done
#6 writing image sha256:96324b5520b19fef0877dffb950a9f7b62ab23dcc65d3f1fb1cb09dabf113c7b
#6 writing image sha256:96324b5520b19fef0877dffb950a9f7b62ab23dcc65d3f1fb1cb09dabf113c7b 0.0s done
#6 naming to docker.io/library/webapplication7:dev done
#6 DONE 0.1s

Describe the results you expected: General information lines should be present on stdout when there is no error.

Additional information you deem important (e.g. issue happens only occasionally):

Output of docker version:

Client: Docker Engine - Community
 Version:           19.03.2
 API version:       1.40
 Go version:        go1.12.8
 Git commit:        6a30dfc
 Built:             Thu Aug 29 05:26:49 2019
 OS/Arch:           windows/amd64
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          19.03.2
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.8
  Git commit:       6a30dfc
  Built:            Thu Aug 29 05:32:21 2019
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc8
  GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

Output of docker info:

Client:
 Debug Mode: false
 Plugins:
  app: Docker Application (Docker Inc., v0.8.0)
  buildx: Build with BuildKit (Docker Inc., v0.3.0-5-g5b97415-tp-docker)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 1
 Server Version: 19.03.2
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc version: 425e105d5a03fabd737a126ad93d62a9eeede87f
 init version: fec3683
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 4.9.184-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 1.952GiB
 Name: docker-desktop
 ID: AVON:LYQZ:TO6V:5KVI:QJDV:E5OH:5EYZ:L6TJ:3AZL:HISV:F5QX:DEFA
 Docker Root Dir: /var/lib/docker
 Debug Mode: true
  File Descriptors: 28
  Goroutines: 43
  System Time: 2019-10-02T21:27:32.2913151Z
  EventsListeners: 1
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: true
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine

Additional environment details (AWS, VirtualBox, physical, etc.): Physical machine. Running docker commands through Containers Tools for Visual Studio.

pratiksanglikar commented 4 years ago

Related issue - https://github.com/microsoft/DockerTools/issues/213

tonistiigi commented 4 years ago

Treating prints to stderr as error is not correct. Stdout is used for actual build results (eg. you can pipe a tarball of the built files) or for id with -q. https://www.jstorimer.com/blogs/workingwithcode/7766119-when-to-use-stderr-instead-of-stdout

bwateratmsft commented 4 years ago

In what scenario is that a thing for Docker? The build output isn't files, it's images, and trying to cram an image into STDOUT...I don't even think that would be possible.

Using STDERR for all logging output, while arguably technically correct, is highly irregular, and likely to cause more problems than solve.

mdonoughe commented 4 years ago

It would be nice to be able to build a container and capture the image ID at the end (like -q) but still have the build output as a separate stream.

tonistiigi commented 4 years ago

@mdonoughe --iidfile

@bwateratmsft

The build output isn't files, it's images

Build output is whatever you define in --output, eg. for stdout docker build -o - . > t.tar

marc-guenther commented 3 years ago

It would be nice to be able to build a container and capture the image ID at the end (like -q) but still have the build output as a separate stream.

How would one do that? Seems not to be possible, normal docker build always writes everything to stdout, and buildkit doesn't write anything to stdout. And --iidfile wants a physical file, so process substitition doesn't work either. :(

Qix- commented 2 years ago

The opinions here by the maintainers are categorically wrong. Unix tools all throughout the ecosystem utilize stderr for progress-like output. Since buildkit's output is highly erratic it wouldn't even make sense to try to capture it to begin with, so the usefulness of outputting it to stdout is limited.

I've run into this issue so many times now, where I would like to capture the resulting ID from stdout but still show the build progress on stderr. Docker tools have always been scripting-hostile and this is no exception - please improve this.

tonistiigi commented 2 years ago

@Qix- I'm not sure who you arguing here with. Buildkit does use stderr and only stderr for progress.

Qix- commented 2 years ago

The ultimate comment still stands - there is no way to extract a resulting image sha from the output of docker build in a standardized way (buildkit or not) akin to -q without also silencing build output.

EDIT: Without brittle text processing commands, which completely disable or break the compact and neatly formatted ANSI-escaped output.

tonistiigi commented 2 years ago

Yes, there is no --write-iid flag. Because we can't add a flag for absolutely every use case. --iidfile is more general and covers more use cases. We can't change the behavior of -q, not because where we write progress but because it is unexpected to the current users. -q first and foremost means "quiet" so printing progress is unexpected whatever the fd is. Another reason we can't print the id is that stdout is already used by -o so we would need to detect conflicts and add confusion to users.

In buildx I would recommend that nobody should use -q as it is a historic hack. Instead, you should configure behavior separately: --iidfile if you want to know the image ID and --progress=quiet if you want to suppress progress output. --progress=quiet does not currently exists in in regular docker build but we are standardizing in https://github.com/docker/cli/pull/3314

erebe commented 2 years ago

Hello, I got hit by this yesterday. We were previously using docker without buildkit and decided to migrate to it to get all the goodies. Long story short, docker/buildkit is integrated in a custom CI, and a low lvl library handling processes was not fair regarding the priority to give to output. (hint: stdout had the priority)

What happened is that, everything went fine at first, but if the build was emitting too many logs, due to unfairness, the process handling the output of buildkit was not picking up line on stderr fast enough. Up to a certain point, the pipe of stderr got full and buildkit build was stuck on write syscall waiting for this pipe to get some room. So after this threshold, everything was working, but was extremly slow...

I double down on moving logs output to stdout, it is not very common to send everything to stderr

computerquip-work commented 2 years ago

Let's say I have a bash script that wants to build an image with docker build, take the resulting image id, and then run it.

With non-BuildKit, the command docker build dir_with_dockerfile 2> /dev/null will output:

Sending build context to Docker daemon  2.048kB
Step 1/1 : FROM ubuntu:bionic
 ---> 886eca19e611
Successfully built 886eca19e611

Pragmatically speaking, this is completely useless. You might could parse the image id out but that's probably not an ideal way to go. The only way to do it currently is to apply the --quiet argument which gives a viable image id.

With BuildKit, the command docker buildx build dir_with_dockerfile 2> /dev/null will output:

It outputs nothing. The logs and progress are output to stderr so redirecting stderr to /dev/null silences the logs. This is still useless because it doesn't output the image id. Ironically, if you give it --quiet, only then will it output the image id.

So, with the above, the problem is there is no way to reliably have both the docker build log / progress output and also obtain the image id in a meaningful way.

What I think should change:

If people want the logs output to stdout, they can redirect stderr to stdout. If they don't want the logs at all, they can redirect it to null or somewhere it's not seen. This gives us the most flexibility.

cocowalla commented 2 years ago

...Since buildkit's output is highly erratic it wouldn't even make sense to try to capture it to begin with

Not if you set BUILDKIT_PROGRESS=plain - then it outputs in a more "standard" fashion. Although it still outputs some lines to stderr that are not even error messages 😞

cocowalla commented 2 years ago

Got hit by this today, after enabling BuildKit in an Azure DevOps pipeline, as AzDo fails tasks by default if anything is written to stderr. AzDo's default has never been an issue for me in years of working with it - it's absolutely bizarre that BuildKit writes stuff to stderr that are not even error messages!! :confused:

I get BuildKit wants some means to redirect image output, but surely that unusual case could be behind a flag?

computerquip-work commented 2 years ago

Got hit by this today, after enabling BuildKit in an Azure DevOps pipeline, as AzDo fails tasks by default if anything is written to stderr. AzDo's default has never been an issue for me in years of working with it - it's absolutely bizarre that BuildKit writes stuff to stderr that are not even error messages!! confused

I get BuildKit wants some means to redirect image output, but surely that unusual case could be behind a flag?

Historically, stderr has been used for logging, so much so that some languages and libraries have called it the log stream. The whole point is that when meaningful output is possible, you use stderr as a means of human-readable output and stdout as a means for pragmatic output.

Frankly, causing anything to fail if something is written to stderr is downright dumb as a default. That behavior should be fixed rather than expecting every application that uses stderr for disposable logs to stop using stderr. I find it more bizarre that this default hasn't caused you more issues.

In addition, it's trivial to redirect stderr to stdout if that's what's wanted.

marc-guenther commented 2 years ago

The whole point is that when meaningful output is possible, you use stderr as a means of human-readable output and stdout as a means for pragmatic output.

Then why is there no meaningful output on stdout? Like, for example, the image sha? Which would allow to do something simple like this, which would be incredibly unbelievably useful: docker run `docker build .` ...

Instead I'm required to... , well, actually I don't even know what I'm required to do, all I know is that something which should be easy and obvious will probably take me at least 30min to figure out, and will require juggling and cleaning up temporary files or some complicated shell redirection magic with non standard file descriptors.

Guys and gals, all I want is to be able to type docker build-n-run mvn install, and Docker builds the container and runs my Maven command inside it (preferably with the directory mounted inside). This is my most common use case. Why is this so complicated? Am I the only one who needs this?

computerquip-work commented 2 years ago

The whole point is that when meaningful output is possible, you use stderr as a means of human-readable output and stdout as a means for pragmatic output.

Then why is there no meaningful output on stdout? Like, for example, the image sha? Which would allow to do something simple like this, which would be incredibly unbelievably useful: docker run `docker build .` ...

Instead I'm required to... , well, actually I don't even know what I'm required to do, all I know is that something which should be easy and obvious will probably take me at least 30min to figure out, and will require juggling and cleaning up temporary files or some complicated shell redirection magic with non standard file descriptors.

Guys and gals, all I want is to be able to type docker build-n-run mvn install, and Docker builds the container and runs my Maven command inside it (preferably with the directory mounted inside). This is my most common use case. Why is this so complicated? Am I the only one who needs this?

That's the whole point of the issue, if you would read my previous reply explaining the changes I think should be made. For reference, other tools like buildah do exactly that.

EDIT: Also, you can already do that with BuildKit.

image_id=$(docker buildx build --quiet -f <Dockerfile>)
docker run "$image_id"

The problem here is you lose diagnostics.

marc-guenther commented 2 years ago

Yes, I absolutely agree. The question is, we have the year 2022, why are easy and obvious changes like this not being made?

EDIT: and of course I would rather prefer to see the diagnostic output...

computerquip-work commented 2 years ago

Yes, I absolutely agree. The question is, we have the year 2022, why are easy and obvious changes like this not being made?

EDIT: and of course I would rather prefer to see the diagnostic output...

Because half the people in the thread appear to think shoving everything into stdout is how things should be done. For the other half, while my suggestion is simple, it has a compatibility break as shown here: https://github.com/moby/buildkit/issues/1186#issuecomment-934804909

EDIT: And mine isn't the only suggestion and it differs slightly from others.

There probably has to be some consensus which appears to be hard to come to.

computerquip-work commented 2 years ago

As an alternative, something like this would also work:

img_file=$(mktemp)
docker buildx build . --iidfile "$img_file"
img_id=$(cat "$img_file")

Just remember to cleanup the temp file.

computerquip-work commented 2 years ago

Sorry for being verbose on the thread (I swear I'm not usually this chatty), but another thing that could be done is just keep --iidfile the way it is but fix the deletion logic. Currently, if you do something like docker buildx build . --iidfile /dev/stdout or docker buildx build . --iidfile >(cat), it fails because it appears to try to delete the iid file first. I'd argue this is probably not desirable to begin with but if that's fixed, the temp file hack above wouldn't be necessary either and it's fully backwards compatible.

marc-guenther commented 2 years ago

Thanks for saving me the 30min. ;) Yea, that's what I meant by require juggling and cleaning up temporary files. Probably something like: trap 'rm -f "$img_file"' 0 Yes, the quoting still interpolates the variable, and yes, this is waaaay too complicated for such a simple task.

tonistiigi commented 2 years ago

@computerquip-work

Any version of docker build should always output only the resulting image id to stdout.

Image ID is what the user needs only for specific types of builds: when build exported an image (into Docker image store), that image was not multi-arch and that image was not exported(eg. in OCI format). Even with all of these constraints most people just want to see the best progress information about their build, not a line in hex.

-q continues to work and output the image ID in stdout if the user wants it for backward compatibility. For everything else stdout works together with -o flag and allows redirecting the output(result) of the build.

Logs and progress should only be put out to stderr.

This is how it is today.

Simply remove the --quiet argument altogether or have it to where it only effects the stderr output.

I agree that we should deprecate it and suggest people to use the new flags that are single purpose and don't do multiple things at once.

@cocowalla

Azure DevOps pipeline, as AzDo fails tasks by default if anything is written to stderr. AzDo's default has never been an issue for me in years of working with it

This claim sounded so bizarre I needed to set up Azure DevOps for the first time. No surprise that it is not the case.

Screen Shot 2022-04-06 at 11 48 01 AM

How do you think the most common unix tools like wget, curl -v, time etc. print their progress information? Or do they fail on every invocation?

@marc-guenther

Then why is there no meaningful output on stdout?

which would be incredibly unbelievably useful: docker run docker build . ...

Instead I'm required to... , well, actually I don't even know what I'm required to do

Stdout is used for -o/--output redirects and for -q for backward compatibility exactly for the case you show in the example. This has been explained numerous times in previous comments.

@computerquip-work

but fix the deletion logic. Currently, if you do something like docker buildx build . --iidfile /dev/stdout or docker buildx build . --iidfile >(cat), it fails because it appears to try to delete the iid file first. I'd argue this is probably not desirable to begin with but if that's fixed, the temp file hack above wouldn't be necessary either and it's fully backwards compatible.

I'm not OK with removing the deletion logic as that is clearly the expected behavior of --iidfile on regular files, but we could detect the /dev/stdout is not a regular file and have a different behavior for it.

computerquip-work commented 2 years ago

I'm not OK with removing the deletion logic as that is clearly the expected behavior of --iidfile on regular files, but we could detect the /dev/stdout is not a regular file and have a different behavior for it.

Is it the file deletion logic that's expected or just that the file is cleared before writing to it? For example, in python (since I don't know how to emulate it in bash), you should be able to open a /dev/stdout device file with truncate mode like so it should work for regular files as well:

f = open('/dev/stdout', 'w+b', buffering=0)
f.write(b'bob\n')
f.close()

This won't work if the filesystem is set to read-only though and other issues.

tonistiigi commented 2 years ago

@computerquip-work Truncate mode is not ideal as it would leave an empty file if there is a crash. It should either clear the file or switch it with an atomic rename(there might be some tricky cases for unprivileged users).

cocowalla commented 2 years ago

@cocowalla This claim sounded so bizarre I needed to set up Azure DevOps for the first time. No surprise that it is not the case.

It certainly is the case with the SSH task (we SSH into a VM to build containers)

bsutton commented 2 years ago

I think we need to go back to conventions and what developers expect of build tools.

All of these build tools (I would guess every other language's build tool) output progress to stdout and errors to stderr. The content of build artifacts are never output to either stdout or stderr.

To break these long-standing conventions is a rather brave and pointless decision.

computerquip-work commented 2 years ago

What problem is being solved by doing that? I'd also argue that's not a long-standing convention, I've seen more projects output to stderr for progress than I have to stdout. If I were to proclaim the opposite as the long-standing convention and say To break these long-standing conventions is a rather brave and pointless decision., there isn't really much discussion to be had and it's not very productive.

bsutton commented 2 years ago

I haven't just proclaimed it, I've given concrete examples of other build tools that all conform to the convention, including Dockers own build tool.

Let me repeat that: including Dockers own build tool.

This reason this thread exist is that this change is a breaking change to docker, a change that appears to provide no benefits and which broke my code and clearly others.

On Fri, 17 June 2022, 1:49 am computerquip-work, @.***> wrote:

What problem is being solved by doing that? I'd also argue that's not a long-standing convention, I've seen more projects output to stderr for progress than I have to stdout. If I were to proclaim the opposite as the long-standing convention and say To break these long-standing conventions is a rather brave and pointless decision., there isn't really much discussion to be had and it's not very productive.

— Reply to this email directly, view it on GitHub https://github.com/moby/buildkit/issues/1186#issuecomment-1157822157, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAG32OB3UHMLT6DFDZQ6DK3VPNEJZANCNFSM4I43Z46A . You are receiving this because you commented.Message ID: @.***>

computerquip-work commented 2 years ago

The "gotcha" arguments are really not productive. The benefit of it is that it allows one to do something like tar=$(docker buildx build -o type=oci,dest=-) without the need to create a temporary file.

If you can make a simple example where you can pragmatically run an image that you just built without race conditions or temporary files, you would have a stronger argument.

tonistiigi commented 2 years ago

@bsutton

The content of build artifacts are never output to either stdout

So because there is a tool on the internet that doesn't have -o, that means that buildkit should not have this feature either?

All of these build tools (I would guess every other language's build tool

Your Github bio says you work with C/C++/Java . What stdio stream do gcc, clang or javac print their progress output?

Qix- commented 2 years ago

It's this sort of philosophic nonsense from the Moby contributors that has forced me to switch to something else entirely. I've advocated against Docker for a few years now due to these bizarre "dying on a hill" stances they take about how tools should behave.

Docker does not behave like any other tool I know of. Its constant misuse of streams, bizarre output formats, and general inoperability with larger systems has rendered it entirely obsolete in my book.

Podman is a step in the right direction, and I urge everyone to focus their time switching to it instead. I'm tired of fighting with the Moby devs over these things. It's been years without any budging.

tonistiigi commented 2 years ago

@Qix-

Docker does not behave like any other tool I know of.

So you don't know gcc, clang, javac, wget, curl, time (only a sample I listed in the last 2 previous comments)?

Please read through the issue and comments before going for the noise. In your previous comment https://github.com/moby/buildkit/issues/1186#issuecomment-934726005 you already wrote

The opinions here by the maintainers are categorically wrong. Unix tools all throughout the ecosystem utilize stderr for progress-like output.

.. without realizing that buildkit does use stderr for progress, and this issue was created by the user who found it confusing and suggested we should change it(what we have refused because it is wrong).

I'm tired of fighting with the Moby devs over these things.

Unfortunately, in both of your last comments, the only person you are fighting with is yourself. You are furiously requesting a behavior that is already there.

bsutton commented 2 years ago

I think you have misunderstood my logic.

So because there is a tool on the internet that doesn't have -o,

If you think there is a use case for a -o switch that outputs the artifacts to stdout then go ahead and do it.

The difference here is that the -o switch is under my control and I choose to use it or not.

Let me detail the problem I'm trying to solve.

Essentially we run a CI/CD environment that builds a no. of docker containers. When reviewing logs from those CI/CD runs the docker builds generate thousands of lines of output, none of which I care about.

Being able to suppress stdout and only outputting stderr lets me efficiently review the logs as I'm only seeing the errors.

This is a daily use case and I suspect a common use case for others.

There seems to be a lot of talk about getting the id out of the build.

Yes, this is useful but there are lots of ways that this can be done and creating a temp file with the id is a perfectly acceptable method.

My rule when developing CLI scripts is that the user owns the console and I should only output to the console what the user has asked me to.

General progress messages go to stdout, errors go to stderr. If there is an error, the app returns a non-zero exit code and I expect to see a descriptive message in stderr.

I consider any CLI that doesn't follow these simple rules to be a badly behaving app.

For what it's worth, I'm the author of DCLI the Dart Console SDK so I feel I have some experience in this area and with what end-users want from a CLI app. dcli.onepub.dev

S. Brett Sutton Noojee Contact Solutions 03 8320 8100

On Fri, 17 Jun 2022 at 07:52, Tõnis Tiigi @.***> wrote:

@bsutton https://github.com/bsutton

The content of build artifacts are never output to either stdout

So because there is a tool on the internet that doesn't have -o, that means that buildkit should not have this feature either?

All of these build tools (I would guess every other language's build tool

Your Github bio says you work with C/C++/Java . What stdio stream do gcc, clang or javac print their progress output?

— Reply to this email directly, view it on GitHub https://github.com/moby/buildkit/issues/1186#issuecomment-1158168767, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAG32OCP7CAKUSHIIJ3NB4LVPOO27ANCNFSM4I43Z46A . You are receiving this because you were mentioned.Message ID: @.***>

computerquip-work commented 2 years ago

You can literally already do that, described in this very thread, with --progress=quiet.

vsiravar commented 2 years ago

Ran into this issue today. In our functional testing suite, we use general information lines to assert tests. Workaround was to use stderr stream. I find it strange that --quiet flag writes to stdout while docker build . does not write anything to stdout. The semantics are a little confusing.

tonistiigi commented 2 years ago

Diagnostics/progress/logs go to stderr. Values to be used with pipes, -o or with id=$(docker build ...) to stdout. That being said, --quiet is there for backward compatibility and if we wouldn't need to worry about that then that case should only be handled with --iidfile.

computerquip-work commented 1 year ago

I just wanted to point out that this is still a bit problematic a year later. While there are workarounds for getting things to work with --iidfile, it's pretty inconvenient to use any time it's not clear if you have a functioning temp directory.

Greatcode88 commented 1 year ago

Is there any progress on this issue?

we are also still facing the same in an Azure DevOps pipeline, where the docker build is called in a bash task.

Please see these screenshots: image

image

tonistiigi commented 1 year ago

FailOnStderr defaults to false in bash task of Azure https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/bash-v3?view=azure-pipelines . Afaics, it is there to handle invoking programs that handle stderr and error codes incorrectly. Builtkit is not such a process and works with the defaults.

AndrewSav commented 10 months ago

Essentially we run a CI/CD environment that builds a no. of docker containers. When reviewing logs from those CI/CD runs the docker builds generate thousands of lines of output, none of which I care about.

Being able to suppress stdout and only outputting stderr lets me efficiently review the logs as I'm only seeing the errors.

This is a daily use case and I suspect a common use case for others.

This is also our use case, and why I ended up on this page. Since --progress=quiet is not reported by docker build --help and as indicated by tonistiigi may disappear when backward compatibility is no longer a concern, what is the proposed solution?

mkstephenson commented 8 months ago

Essentially we run a CI/CD environment that builds a no. of docker containers. When reviewing logs from those CI/CD runs the docker builds generate thousands of lines of output, none of which I care about. Being able to suppress stdout and only outputting stderr lets me efficiently review the logs as I'm only seeing the errors. This is a daily use case and I suspect a common use case for others.

This is also our use case, and why I ended up on this page. Since --progress=quiet is not reported by docker build --help and as indicated by tonistiigi may disappear when backward compatibility is no longer a concern, what is the proposed solution?

Ditto, the problem with redirecting is that it requires more effort to detect when a build has actually failed (you have to store the output somewhere and then parse it again to see if anything starts with ERROR, if so, fail the task compared to just failing if errors are written stderr).

nkmittal commented 6 months ago

This is quite irritating - I faced this issue when recently deploying Docker on a fresh Ubuntu install. Had to revert back to older version of Docker.

ozydingo commented 4 months ago

Ditto, the problem with redirecting is that it requires more effort to detect when a build has actually failed (you have to store the output somewhere and then parse it again to see if anything starts with ERROR, if so, fail the task compared to just failing if errors are written stderr). That should be more robust and easier than scanning for error in the command output.

Are you able to use the exit code of the build command? For example, when I build an image with an error, I'll get an exit code of 1. A successful build returns exit code 0. If you're on some bash / zsh / similar, you can use set -e in the build script to fail the script at that point.

You can also explicitly read the exit code as in

docker build ...
if [ $? -ne 0 ]; then
  echo "Build failed"
  exit 1
fi

You can also inline it

docker build ... || { echo "failed to build"; exit 1 }
ejalee-of-fincra commented 2 months ago

Ditto, the problem with redirecting is that it requires more effort to detect when a build has actually failed (you have to store the output somewhere and then parse it again to see if anything starts with ERROR, if so, fail the task compared to just failing if errors are written stderr). That should be more robust and easier than scanning for error in the command output.

Are you able to use the exit code of the build command? For example, when I build an image with an error, I'll get an exit code of 1. A successful build returns exit code 0. If you're on some bash / zsh / similar, you can use set -e in the build script to fail the script at that point.

You can also explicitly read the exit code as in

docker build ...
if [ $? -ne 0 ]; then
  echo "Build failed"
  exit 1
fi

You can also inline it

docker build ... || { echo "failed to build"; exit 1 }

Worked like charm.