moby / moby/buildkit

Proposal: Propagate exit code for failing RUN commands

Open
#2,913 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
10.3k
Forks
1.5k
Avg merge
1d 23h
Merged PRs (30d)
48

Description

If a RUN command fails when using buildkit, docker currently always exits with exit code 1 no matter what exit code the original command produced. It would be useful to propagate the command's exit code out to the shell so those failures have a chance to be distinguishable from errors of the docker engine.

Docker version 20.10.16, build aa7e414

Example Dockerfile,

FROM alpine:latest
RUN exit 123

Without buildkit, the RUN command's exit status is available to the shell,

$ DOCKER_BUILDKIT=0 docker build .; echo "build exit status is: $?"
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine:latest
 ---> e66264b98777
Step 2/2 : RUN exit 123
 ---> Running in 45def427bdd8
The command '/bin/sh -c exit 123' returned a non-zero code: 123

build exit status is: 123

A failure from the engine (I deleted a cache dir) returns a distinguishable 1 exit code,

$ DOCKER_BUILDKIT=0 docker build .; echo "build exit status is: $?"
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine:latest
 ---> e66264b98777
Step 2/2 : RUN exit 123
open /var/lib/docker/overlay2/6ae2b51f5d0afdf49509f10a2c55476fc068b7436321c443cd0a23fc09c80d1b/committed: no such file or directory

build exit status is: 1

With buildkit, the exit status is always 1 when the RUN command fails

$ DOCKER_BUILDKIT=1 docker build .; echo "build exit status is: $?"
...
#5 [2/2] RUN exit 123
#5 sha256:136f9a7caa0b737f748cca87a56ede17c6681d8ebec4a05acedf9aac3afd41bd
#5 ERROR: executor failed running [/bin/sh -c exit 123]: exit code: 123
------
 > [2/2] RUN exit 123:
------
executor failed running [/bin/sh -c exit 123]: exit code: 123

build exit status is: 1

and when the docker engine fails

$ DOCKER_BUILDKIT=1 docker build .; echo "build exit status is: $?"
[+] Building 0.1s (5/5) FINISHED
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 43B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
 => [internal] load metadata for docker.io/library/alpine:latest           0.0s
 => CACHED [1/2] FROM docker.io/library/alpine:latest                      0.0s
 => ERROR [2/2] RUN exit 123                                               0.0s
------
 > [2/2] RUN exit 123:
------
failed to prepare kcywk5z6l6azc6amb8bs9en7h: open /var/lib/docker/overlay2/6ae2b51f5d0afdf49509f10a2c55476fc068b7436321c443cd0a23fc09c80d1b/committed: no such file or directory

build exit status is: 1

This makes it difficult to programmatically determine where the failure is.

In a real use case, in CI pipelines, I would be able to run docker prune to reset the cache and retry the build when the engine fails (almost all of our routine engine errors are because of a corrupt overlay cache). Whereas I could notify the application team if it's a RUN failure.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue with the provided Dockerfile containing RUN exit 123, comparing DOCKER_BUILDKIT=0 and DOCKER_BUILDKIT=1 through docker build. Trace the build command's exit status and distinguish a failed RUN command from the documented engine error; done means the original RUN exit code is propagated while engine failures remain distinguishable.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, go
Domain
build-system, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.