由于 "no such file or directory" 导致 gitlab CI 失败

Failing gitlab CI due to "no such file or directory"

我正在尝试让我的 .gitlab-ci.yml 文件使用 Gitlab 容器注册表之外的图像。我已成功将 Dockerfile 上传到注册表,我可以从本地计算机上的注册表中提取图像并构建一个容器就好了。但是,在为我的 .gitlab-ci.yml 文件使用图像时,我收到此错误:

Authenticating with credentials from job payload (GitLab Registry)
standard_init_linux.go:190: exec user process caused "no such file or directory"

我看到过很多关于 Windows EOL 字符的讨论,但我 运行 在 Raspbian 上,我认为这不是问题所在。但是,我对此很陌生,无法弄清楚问题是什么。感谢您的帮助。

.gitlab-ci.yml 文件:

before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

stages:
    - test-version

test:
    stage: test-version
    image: registry.gitlab.com/my/project/test:latest
    script:
        - python --version 

test.Dockerfile(在注册表中为 registry.gitlab.com/my/project/test:latest):

ARG base_img="python:3.6"                                                                                                                                                                                                                    
FROM ${base_img}

# Install Python packages
RUN pip install --upgrade pip

编辑: 另一件需要注意的事情是,如果我将 .gitlab-ci.yml 文件中的图像更改为 python:3.6,那么它运行得很好。只有当我尝试 link 我在注册表中的图像时才会出现。

正如您在评论中确认的那样,gitlab.com/my/project 是一个私有存储库,因此不能直接使用 docker pullimage: 属性 和 registry.gitlab.com/my/project/test:latest.

但是,您应该能够通过使用 image: docker:latest 和手动 运行 docker 命令(包括 docker login)来调整 .gitlab-ci.yml

这就靠所谓的Docker-in-Docker (dind) approach, and it is supported by GitLab CI.

Here is a generic template of .gitlab-ci.yml relying on this idea:

stages:
  - test-version

test:
  stage: test-version
  image: docker:latest
  services:
    - docker:dind
  variables:
    # GIT_STRATEGY: none  # uncomment if "git clone" is unneeded
    IMAGE: "registry.gitlab.com/my/project/test:latest"
  before_script:
    # - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
    # or better
    - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"

  script:
    - docker pull "$IMAGE"
    - |
      docker run --rm -v "$PWD:/build" -w /build "$IMAGE" /bin/bash -c "
        export PS4='+ \e[33;1m($0 @ line $LINENO) $\e[0m '  # optional
        set -ex  # mandatory
        ## TODO insert your multi-line shell script here ##
        echo \"One comment\"  # quotes must be escaped here
        : A better comment
        python --version
        echo $PWD  # interpolated outside the container
        echo $PWD  # interpolated inside the container
        ## (cont'd) ##
      " "$CI_JOB_NAME"
    - echo done

这会导致更多样板文件,但这是通用的,因此您只需替换 IMAGE 定义并将 TODO 区域替换为您自己的 Bash 脚本,只需确保这两项已完成:

  • 如果你的 shell 代码中包含一些双引号,你需要将它们转义,因为整个代码被 docker run … "" 包围(最后一个变量 "$CI_JOB_NAME" 是一个细节,它是可选的,只允许一个人覆盖 Bash 变量 PS4)
  • 中引用的 [=25=] 变量
  • 如果您的 shell 代码包含局部变量,则需要对它们进行转义(参见上面的 \$PWD),否则这些变量将在 运行 docker run … "$IMAGE" /bin/sh -c "…" 之前解析命令本身。