Gitlab-Runner 本地构建-从非 TTY 设备登录

我试图在 Linux 上使用 gitlab-runner 在本地构建我的项目。

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"

不幸的是,我的尝试以“ docker login”无法从非 TTY 设备执行交互式登录的错误结束。

$ 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

我的问题是,是否有人偶然发现了这个问题,以及如何成功地执行构建?

108110 次浏览

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

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

Although I didn't get this error for git-lab, I got it while pulling a different image.

The issue was with using git bash on Windows. Switch to PowerShell prompt and then try the following:

docker login

I had the same issue, but for a different cause than those already listed in here.

This is my gitlab-ci command:

docker login "${AZURE_ACR_URL}" -u "${AZURE_ACR_ACCOUNT}" -p "${AZURE_ACR_PASSWORD}"

My pipeline was running fine on the master branch, but not on other branches. Why? Because I defined the AZURE_ACR_PASSWORD variable via the settings/ci_cd feature, with the "protected" flag. After reading what this protected flag means I understood why my AZURE_ACR_PASSWORD variable could not be seen in the command:

This variable will be passed only to pipelines running on protected branches and tags

Try this. docker login -u Username -p Password

It worked for me.

Reading how protected variables are working solved it for me. I need to perform this action inside a protected branch since I also protected my variables.

If you are not using a protected branch better remove protected variables and try again.

If you only need to log into one registry, you can get the token (from looking at .docker/config.json after a console login or sometimes via the registry itself in the case of Artifactory). Then just echo the results to .docker/config.json

echo '{ "auths": { "https://awesome_docker_repsitory.com": { "auth": "c4ajLWdpqGxhYi3xYsQ6qVa4aUefY0xbd1t6dtc4YnQ3y2DYTDoOWONx", "email": "bitbucket@foo.bar" } } }' > ~/.docker/config.json"


This performs the same action as the docker login (if you don't have a docker credential helper that is).

Error: Cannot perform an interactive login from a non TTY device is your typical red herring message. You have to look beyond the message, or rather, before. It wants to use interactive login as a fallback solution, because the previous login failed. Just like in Unix when your ssh2 auth attempt is rejected. It then prompts for username/password. Except that for emulation of Unix terminals it may fail.

The general answer to this is: Review each of your parameters, in your command line, and make sure it is what you think it is. A trick is to precede your overall command line with echo, so as to resolve all variables...

Below worked for me for Docker 1.13 ( Rhel-7.8 ):

  1. Create a file with your password / ECR key
  2. use command docker login --username AWS -p 'cat /data/user/ecr/key' registry-url.amazonaws.com

Note: In step 2 please replace ' with ` while using the command

For those that are using variables that are set in settings of GitLab CI/CD, unmark the options protected and masked. Optionally simply unmarking protected works fine without masked unchecked as well.

This will figure out the docker login problem.

if your here because your getting the error in git hubs workflows (actions). the easiest way to login is the docker login-action step: https://github.com/marketplace/actions/docker-login#github-packages-docker-registry

-   name: Login to GitHub Packages Docker Registry
uses: docker/login-action@v1
with:
registry: docker.pkg.github.com
username: $\{\{ github.repository_owner }}
password: $\{\{ secrets.GITHUB_TOKEN }}

or for windows build agents:

-   name: Login
shell: pwsh
env:
GITHUB_TOKEN: $\{\{ secrets.GITHUB_TOKEN }}
run: echo $env:GITHUB_TOKEN | docker login https://docker.pkg.github.com -u ${env:GITHUB_ACTOR} --password-stdin

For those who are trying to ssh to a remote host for deploying a docker image via gitlab-ci:

Some variables like $CI_DEPLOY_USER $CI_DEPLOY_PASSWORD CI_JOB_TOKEN and others are not been sent through ssh to the remote server because they are not shared vars.

You need to create a deploy token via config >> repository >> deploy token. This applies for your group or for a specific project.

Then create 2 variables on the project or group via configs >> ci /cd >> variables. The names could be MASTER_DEPLOY_USER and MASTER_DEPLOY_TOKEN

Then you could login like following

deploy-development:
stage: deploy-development
image: kroniak/ssh-client
only:
- my_development_branch
before_script:
- eval $(ssh-agent -s)
- echo "$YOUR_SERVER_SSH_PRIV_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- ssh-keygen -R $YOUR_REMOTE_HOST || true
# login to docker on auth machine with deploy credentials
- >
ssh root@${YOUR_REMOTE_HOST}
"docker login -u $MASTER_DEPLOY_USER -p $MASTER_DEPLOY_TOKEN $CI_REGISTRY"

Make sure you define also the other needed variables like YOUR_REMOTE_HOST and YOUR_SERVER_SSH_PRIV_KEY.

use this bit of code instead for your docker login:

echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin

In my case i was trying to connect to an AWS-Repo.

aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/XYZ

After reading the other answers i just ran the first part of the command:

aws ecr-public get-login-password --region us-east-1

This resulted in a new Error:

"...is not authorized to perform: sts:GetServiceBearerToken..."

This error message was used as the password and therefore did not work. So don't get misdirected by the error and search for the root cause.

For AWS-User: I added the following two Permissions:

AWSKeyManagementServicePowerUser, AWSCodeArtifactAdminAccess

In my case, ' let variables not work

ssh xxx@xxx 'docker login ${REGISTRY} -u ${REGISTRY_USER} -p ${REGISTRY_PASSWORD} && dosomething'

So, you should not use '. There are many ways to reach it.