尽管返回 0,Gitlab CI 作业仍失败 - Docker 镜像有问题

问题描述 投票:0回答:1

我有一个 Gitlab CI 作业失败,尽管最后一个命令返回 0。最小脚本的运行(仅执行

ps -a
echo $?
)日志如下:

$ ps -A
    PID TTY          TIME CMD
      1 ?        00:00:00 bash
      9 ?        00:00:00 bash
     19 ?        00:00:00 ps
$ echo $?
0
Cleaning up file based variables 00:01
ERROR: Job failed: exit code 1

我将问题范围缩小到使用的 Docker 映像 - 同一个作业在同一个运行器上运行,但使用另一个映像按预期成功。

这是(有问题的图像的)Dockerfile:

FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
    apt-get install -qq -y \
    locales sudo python3 \
    python3-pip python3-pexpect python3-git python3-jinja2 python3-subunit \
    binutils build-essential bzip2 chrpath cpio cpp curl debianutils diffstat \
    file g++ gawk gcc git iputils-ping libacl1 libgnutls28-dev liblz4-tool \
    libtinfo5 make patch socat unzip wget xz-utils zstd zip

RUN locale-gen "en_US.UTF-8" && update-locale LANG=en_US.UTF-8

RUN useradd -m bb && \
    usermod -aG sudo bb && \
    mkdir -p /home/bb && \
    chown -R bb:bb /home/bb && \
    usermod --shell /bin/bash bb && \
    echo "bb ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/no_password

ENTRYPOINT exec /bin/bash -l
WORKDIR /home/bb
USER bb

知道可能出了什么问题,或者如何进一步调试吗?不幸的是,使用

--debug
在本地运行器上运行并不能提供更多的见解。

docker gitlab dockerfile gitlab-ci-runner
1个回答
0
投票

您应该删除 Dockerfile 的

ENTRYPOINT
行。

您目前拥有

ENTRYPOINT exec /bin/bash -l

请注意,这是一个 shell 形式的命令(没有 JSON 数组语法),因此 Docker 自动将其包装在

/bin/sh -c
中。 这是特别有问题的,因为
CMD
作为参数传递给入口点,但
sh -c
通常会忽略它的参数。 例如,如果您的自动化运行

docker run --rm your-image ls /app

那么主容器命令就变成了

/bin/sh -c 'exec /bin/bash -l' ls /app

以及

sh -c
字符串后面的参数在字符串内作为位置参数
$0
$1
可见,但它们不会自行执行,除非您的
ENTRYPOINT
值小心使用它。

听起来您可能正在尝试构建一组工具,以某种其他实体可以使用的方式(例如,作为 Jenkins 构建器容器),而无需在其中打包特定的单个应用程序。 在这种情况下,您可以完全省略

ENTRYPOINT
CMD
;您将从基本映像继承这些设置(通常仍默认运行 shell),并期望运行容器的任何实体提供自己的命令。

更一般地说,我建议,如果您确实包含

ENTRYPOINT
,则它 always 应使用 JSON 数组语法,以免丢失任何调用者提供的命令。 我倾向于将容器将要运行的实际命令放在 Dockerfile
CMD
中,如果您确实包含
ENTRYPOINT
,请使其成为以
exec "$@"
结尾的 shell 脚本,以运行容器给出的任何命令。

© www.soinside.com 2019 - 2024. All rights reserved.