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
...
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With