Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make Docker build stop after if RUN fails in multi-stage build

I have a Dockerfile which has multiple stages. An intermediate stage runs tests. If the test fails, I would like the build to stop but it continues given below. You can see output where it continues beyond failed RUN command.

# Base image
FROM python:3.5 as base


# For running tests
FROM base
WORKDIR /root

RUN mkdir /root/src
ADD src/requirements.txt /root/src
RUN pip install -r /root/src/requirements.txt

ADD . /root
RUN ["/bin/bash", "-c", "cd test; ./run-tests.sh"]


# For publishing src files

FROM base
ADD src /root/src
ADD .pypirc /root/.pypirc


WORKDIR /root/src

CMD python setup.py sdist upload -r local

Output:

Step 6/13 : RUN pip install -r /root/src/requirements.txt
 ---> Using cache
 ---> 56fa7fc2f2e8
Step 7/13 : ADD . /root
 ---> 74c52977edcf
Step 8/13 : RUN ["/bin/bash", "-c", "cd test; ./run-tests.sh"]
 ---> Running in 68a184ab54af
...
----------------------------------------------------------------------
Ran 1 test in 10.122s

FAILED (failures=1)
The command '/bin/bash -c cd test; ./run-tests.sh' returned a non-zero code: 1
running sdist
running egg_info
...
running upload
Submitting dist/<artifact-name>-2.6.1.2.tar.gz to https://<subdomain>.jfrog.io/<context>/api/pypi/python-local
...
like image 817
Rag Avatar asked Feb 12 '19 08:02

Rag


People also ask

How do you stop a container after Docker run?

docker rm -f The final option for stopping a running container is to use the --force or -f flag in conjunction with the docker rm command. Typically, docker rm is used to remove an already stopped container, but the use of the -f flag will cause it to first issue a SIGKILL.

How do you abort a Docker build?

To stop one or more running Docker containers, you can use the docker stop command. The syntax is simple: $ docker stop [OPTIONS] CONTAINER [CONTAINER...] You can specify one or more containers to stop.

How does Docker multi stage build work?

With multi-stage builds, you use multiple FROM statements in your Dockerfile. Each FROM instruction can use a different base, and each of them begins a new stage of the build. You can selectively copy artifacts from one stage to another, leaving behind everything you don't want in the final image.

Does Docker stop wait?

Docker has limited patience when it comes to stopping containers. There's a timeout, which is 10 seconds by default for each container. If even one of your containers does not respond to SIGTERM signals, Docker will wait for 10 seconds at least.


1 Answers

Your command, run-tests.sh, needs to exit with a non-zero exit code and docker will stop building. In this case, that has happened:

The command '/bin/bash -c cd test; ./run-tests.sh' returned a non-zero code: 1

Whatever you run to call docker build needs to handle that exit code and stop running at that point. Docker's behavior is to give you an exit code to indicate the failure:

$ cat df.fail
FROM busybox
RUN exit 1
RUN echo still running

$ docker build -f df.fail .
Sending build context to Docker daemon  23.04kB
Step 1/3 : FROM busybox
 ---> 59788edf1f3e
Step 2/3 : RUN exit 1
 ---> Running in 70d90fb88d6e
The command '/bin/sh -c exit 1' returned a non-zero code: 1

$ echo $?
1

From the above example, you can see that docker does stop as soon as the command returns a non-zero exit code, it does not run the echo still running line, and there's a non-zero return code from docker build itself that you can handle with whatever you use to run the build.

like image 84
BMitch Avatar answered Oct 12 '22 14:10

BMitch