12

I am using docker on windows (Docker for Windows, not Docker Toolbox) and aws cli in cygwin ("git bash") shell. I'm trying to push a docker image into AWS ECR - the private ECS repository.

Whatever I do - when I'm running docker push I repeatedly get:

no basic auth credentials

Method 1

I have been following instructions and running the standard commands:

$ $(aws --profile myprofile ecr get-login --region us-east-1)
Login Succeeded
$ docker tag myrepo:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo:latest
$ docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo:latest
The push refers to a repository [232097583865.dkr.ecr.us-east-1.amazonaws.com/potion]
688f61a6956d: Preparing
11908ead416e: Preparing
no basic auth credentials

No success.

Trying to pull reveals that indeed, I don't have access:

$ docker pull 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo
Using default tag: latest
Pulling repository 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo
unauthorized: authentication required

However docker does think that I'm logged in:

$ docker logout https://123456789.dkr.ecr.us-east-1.amazonaws.com
Remove login credentials for https://123456789.dkr.ecr.us-east-1.amazonaws.com

# let's run again - should not be logged in now
$ docker logout https://123456789.dkr.ecr.us-east-1.amazonaws.com
Not logged in to https://123456789.dkr.ecr.us-east-1.amazonaws.com

Hmm.

Method 2

Internet suggests dissecting the command and using an older procedure to log on.

Basically boils down to something like this:

docker login -u AWS -p $(aws --profile myprofile ecr get-authorization-token --region us-east-1 --output text --query authorizationData[].authorizationToken | python -c 'import base64, sys; print base64.b64decode(sys.stdin.read())' | cut -d: -f2) https://123456789.dkr.ecr.us-east-1.amazonaws.com

This also seems to succeed, but docker push or pull result in the same failure.

Other Dead Ends

Windows and cygwin is weird. So, let's put the docker login command in a shell script file, and run it, or source it. No success.

Generating additional AMI profiles with explicit access tokens and new sets of credentials. No success.

Exporting the AWS credentials as environment variables and repeating the process. No success.

Using the awesome aws-temp-token.sh script that takes an MFA code and generates session credentials as environment variables. No success (though the tool is a life saver at other times, so use it).

Spoiler Alert

I did eventually manage to solve this problem. It was so frustrating though and I found no online mention of the solution, so writing an answer should hopefully relieve some of the mental pain.

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
Yonatan
  • 1,187
  • 15
  • 33

5 Answers5

18

One of my searches led me to this answer, which while irrelevant to my case, brought to my attention the place where authentication credentials are stored: the docker config.json file. Take a look here to read more about it and its auth usage.

However, my own file had these contents after logging in with any of the methods above:

{
    "auths": {
        "https://123456789.dkr.ecr.us-east-1.amazonaws.com": {}
    },
    "credsStore": "wincred"
}

The explicit mention of Windows (wincred) caught my attention. Reading more into this, it appears docker on Windows uses a helper credential store which is probably better than storing credentials as plain text on the file system (it's normally stored as base64 which is greek for "plain text").

However - the solution came when I manually edited this file to contain the authentication token directly.

I generated my authentication token with this command (output shortened for brevity):

$ aws --profile myprofile ecr get-authorization-token --region us-east-1 --output text --query authorizationData[].authorizationToken
jFHNnVxZ............Vqc==

After editing ~/.docker/config.json, it looked something like this:

{
    "auths": {
        "https://123456789.dkr.ecr.us-east-1.amazonaws.com": {
            "auth": "jFHNnVxZ............Vqc=="
        }
    }
}

And with this in place, the push is finally successful:

$ docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo:latest
The push refers to a repository [123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo]
61a69688f56d: Pushed
11ad4908e16e: Pushed
myrepo: digest: sha256:20c0f3......82aa19 size: 42162

And all is well once more.

Community
  • 1
  • 1
Yonatan
  • 1,187
  • 15
  • 33
6

Extending your own brilliant answer which got me out of jail. I found that if you remove:

,
"credsStore": "wincred"

Save the file, run the docker login command again it will put the credentials directly in config.json which I found to work.

Leaving something a little like

{
    "auths": {
        "https://407163548648.dkr.ecr.eu-west-1.amazonaws.com": {
            "auth": "QV...Nbz0=",
            "email": "AWS"
        }
    }
}
3

Adding more to the above, this probably merits an issue raised with Docker for AWS compatibility and an issue with AWS for documentation. Docker is doing the right thing in this case by using the Windows credential store however AWS is trying to overload basic auth with certificate auth.

Specifically, running docker login actually does add the entry to your Windows credential store. You can see this by opening Credential Manager, select "Windows Credentials" and you'll see a new entry for the https://12345678.dkr.ecs.region.amazonaws.com URL you entered.

The issue is that AWS is using a public key as a password and Windows won't let you enter a password that long. You can try this by copying the password from AWS, editing the stored credential and trying to paste the value in. Windows won't let you.

Dan
  • 293
  • 1
  • 3
  • 8
2

Step 1: Get your Auth Token:

aws --profile default ecr get-authorization-token --region us-east-1 --output text --query authorizationData[].authorizationToken

(Note: if you have a profile then change the default to your profile name)

step 2: Edit your ~/.docker/config.json

{
"auths": {
    "https://45456644454545.dkr.ecr.us-east-1.amazonaws.com": {
        "auth": "TRdfdhwe53hsdshhSdSHdsdssdsd...GGSDe="
    }
  }

}

Step 3: now you can push your docker image.

1

Try this:

eval $(aws ecr get-login --no-include-email | sed 's|https://||')
t j
  • 7,026
  • 12
  • 46
  • 66
yaboong
  • 157
  • 3
  • 18