Search code examples
dockergitlabdockerfilegitlab-ciraspbian

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


I'm attempting to have my .gitlab-ci.yml file use an image off the Gitlab container registry. I have successfully uploaded the Dockerfile to the registry and I can pull the image from the registry on my local machine and build a container just fine. However, when using the image for my .gitlab-ci.yml file, I get this error:

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

I've seen a bunch of discussion about Windows EOL characters, but I'm running on Raspbian and I don't believe that's the issue here. However, I'm pretty new at this and can't figure out what the issue is. I appreciate any help.

.gitlab-ci.yml file:

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 (which is in the registry as registry.gitlab.com/my/project/test:latest):

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

# Install Python packages
RUN pip install --upgrade pip

Edit: Another thing to note is that if I change the image in the .gitlab-ci.yml file to just python:3.6, then it runs just fine. It's only when I attempt to link my image in the registry.


Solution

  • As you confirmed in the comments, gitlab.com/my/project is a private repository, so that one cannot directly use docker pull or the image: property with registry.gitlab.com/my/project/test:latest.

    However, you should be able to adapt your .gitlab-ci.yml by using the image: docker:latest and manually running docker commands (including docker login).

    This relies on the so-called 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
    

    This leads to a bit more boilerplate, but this is generic so you can just replace the IMAGE definition and replace the TODO area with your own Bash script, just ensuring that the two items are fulfilled:

    • If your shell code contains some double quotes, you need to escape them, because the whole code is surrounded by docker run … " and " (the last variable "$CI_JOB_NAME" is a detail, it is optional and just allows one to override the $0 variable referenced within the Bash variable PS4)
    • If your shell code contains local variables, they need to be escaped (cf. the \$PWD above), otherwise these variables will be resolved prior running the docker run … "$IMAGE" /bin/sh -c "…" command itself.