多阶段构建中,如果RUN命令失败,如何让Docker停止构建?

11

我有一个Dockerfile,其中包含多个构建阶段。中间阶段运行测试。如果测试失败,我希望构建停止,但它会继续执行以下步骤。您可以看到输出结果,它超出了失败的RUN命令。

# 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

输出:

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
...
1个回答

9

您的命令run-tests.sh需要以非零退出码退出,Docker将停止构建。在这种情况下,已经发生了这种情况:

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

无论你运行什么来调用docker build,都需要处理该退出码并在此时停止运行。 Docker的行为是给你一个退出码来指示失败:

$ 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

从上面的例子中,可以看出当命令返回一个非零退出码时,Docker 就会停止运行,它不会执行 echo still running 这一行代码,并且 docker build 本身也会返回一个非零的退出码,你可以使用任何工具来运行构建并处理这个退出码。

运行命令失败,退出代码为1。命令/bin/bash -c cd test; ./run-tests.sh返回了非零代码:1。 - Rag
@Rag 我刚才看漏了。似乎 Docker 构建失败了。需要在启动 Docker 构建的脚本中添加错误处理。 - BMitch
1
这里的问题似乎是它在前一个阶段失败的情况下仍然运行下一个阶段。 - Rag
@Rag 如果你所说的下一阶段是指运行 python setup.py sdist upload -r local,那么你应该注意到即使构建成功,它也不会在构建期间运行。它是在 docker build 命令退出后运行的。请更新你的问题,包括命令本身的完整输出以及在构建完成后是否看到提示。 - BMitch
好的,问题是我有一个bash脚本来构建Docker镜像并在之后运行该镜像。它没有查看先前命令(Docker build)的退出代码。现在我已经设置了set -e - Rag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接