Gitlab-runner local build - login from non TTY device

I'm trying to build my project locally using gitlab-runner on Linux.

docker-build:
  stage: build
  image: docker:latest
  script:
    - docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY # user "gitlab-ci-token" is automatically created by GitLab
    - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME" target/
    - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME"

Unfortunately my attempts end with error about "docker login" not being able to perform interactive login from non-TTY device.

$ gitlab-ci-multi-runner exec docker --docker-privileged docker-build
Running with gitlab-ci-multi-runner 1.11.1 (a67a225)
  on  ()
Using Docker executor with image docker:latest ...
Starting service docker:dind ...
Pulling docker image docker:dind ...
Waiting for services to be up and running...
Pulling docker image docker:latest ...
Running on runner--project-1-concurrent-0 via vanqyard...
Cloning repository...
Cloning into '/builds/project-1'...
done.
Checking out 70187b2d as docker-basic-conf...
Skipping Git submodules setup
Checking cache for docker-build/docker-basic-conf...
Successfully extracted cache
$ docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
Error: Cannot perform an interactive login from a non TTY device
ERROR: Job failed: exit code 1
FATAL: exit code 1 

My question is has anybody stumbled upon this issue and how to succesfunlly perform build?


Solution 1:

Probably not linked to the problem here, but some people might encounter the exact same message when trying a docker login from a Linux like terminal on Windows such as Git bash or Docker quickstart terminal or even Cygwin.

The trick here is to use winpty docker login

Solution 2:

Most likely you did not specify the variables $CI_JOB_TOKEN and $CI_REGISTRY for the project you are working on. Note that variables are not shared and are only set per project!

That's also why you encounter the error message

"flag needs an argument: 'p' in -p"

when you try to do the docker login without the quotes, which is the right way because otherwise $CI_JOB_TOKEN is not recognized as a variable, but it is simply a string consisting of two quotes, a dollar sign and the sequence of chars "CI_JOB_TOKEN".

Assuming your variables are not set and you try to execute the command

docker login -u "gitlab-ci-token" -p $CI_JOB_TOKEN $CI_REGISTRY

the variables are evaluated and your command essentially looks like that:

docker login -u "gitlab-ci-token" -p

The -p flag is not followed by a password and for that reason docker tries to initialize an interactive login.

You can verify this by trying to output your variables when you include the command echo $CI_JOB_TOKEN in your .gitlab-ci.yml