I am experiencing an issue “Error: Cannot perform an interactive login from a non TTY device” in a GitLab CI/CD pipeline. The pipeline has four stages build, test, review, and deploy, however, “$ docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD $CI_REGISTRY” works fine for ‘stage: build’, but fails for ‘stage: deploy’. Found this article so the ‘master’ branch is protected, but did not help.
build_job:
stage: build
image: docker:20.10.16
services:
- name: docker:20.10.16-dind
alias: docker
variables:
#CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
# LOGS:
$ docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
deploy_job:
stage: deploy
image: docker:20.10.16
services:
- name: docker:20.10.16-dind
alias: docker
variables:
#CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
script:
- docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD $CI_REGISTRY
- docker run -d -p 3000:3000 $CONTAINER_RELEASE_IMAGE
environment:
name: production/$CI_COMMIT_REF_SLUG
url: https://$CI_ENVIRONMENT_SLUG.example.com
#LOGS:
$ docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD $CI_REGISTRY
Error: Cannot perform an interactive login from a non TTY device
Cleaning up project directory and file based variables
00:00
ERROR: Job failed: exit code 1
Any help, please?
Thanks!
2
Answers
Following the @hakre explanation here above, the solution leads me to two subsequent errors, however, it helped me solve the "Error: Cannot perform an interactive login from a non TTY device".
First, by adding the following command in the pipeline:
It started throwing the error:
So, modified the command to:
In which started throwing the following error:
Thus, created a personal access token, which solved the issue:
The "Error: Cannot perform an interactive login from a non TTY device" emitted by the
docker(1)
command for a command like yours in the gitlab job:The message is a bit misleading because
docker login
is quite lax here. Even you specified to read the password as string from the command-line (-p
or--password
option), if the password is missing or wrong,docker login
will ask for it.As this makes no sense within a gitlab CI automation – there is no interactive terminal (TTY) – the
docker login
command is at least clever enough to realize that and quits with the bespoken error message.So if you get that error, you were not able to properly provide the password.
The Missing Credentials Docker Login Situation in Gitlab CI/CD
You can change the
docker login
command to make it a bit more robust, especially within CI runs.Let’s shortly review the usage and better understand the problem to then make some suggestions how to improve. From
docker login --help
:Given your original command-line:
and considering an error and all those three Gitlab CI/CD variables are empty, the command-line would look like the following:
That is login with the username "-p" to the default server.
You can simulate that on your own shell by running this command with standard-input closed:
Exactly that error message.
Always quote
"$VARIABLES"
Looking closer at the actual command-line, the error message is a reminder to always quote the variables1. Also for explicitness use the options delimiter
--
:In the error case those variables are empty the command then is:
The behaviour is still the same thought, the docker login command still tries hard, and it’s not yet giving a good message.
The
--password-stdin
optionTherefore within a non-interactive session (like the gitlab-runner) it is strongly recommended:
Use the
--password-stdin
option. Not only to prevent the warning in the case of a successful login but to make docker login to actually complain about the empty username in the first place! Also it allows to specify it before the username argument option to remove another ambiguity:Now even if the variables are missing, the command still fails in a good way:
Remarks:
'
), which turned out to be wrong after Franks’ answer with the final conclusion. Better than single-quotes for this Gitlab CI job with a Linux/Unix (shell)script
, the variables need to be quoted with double quotes ("
) instead, as they are substituted by the shell and not – as assumed earlier – when the shell script is generated by the runner for its executor. Under that wrong impression I had considered single-quotes a better fit as their content won’t be substituted by the shell then, but substituting within the shell is much better now (and much more stable/safe by the gitlab runner to do it this way now as I think about it).