简体   繁体   中英

docker login to ECR via python docker SDK

python3 along with https://docker-py.readthedocs.io/en/stable/

I am just curious, that when I login to ecr (via aws ecr get-login) my docker deamon on my PC remembers the token and even if restart shell i can login to ECR until token expires. I can even see that in the ~/.docker/config.json file in the auths key

Surprisingly, logging in thru python docker SDK:

ecr_client = boto3.client('ecr')
    token = ecr_client.get_authorization_token()
    username, password = base64.b64decode(token['authorizationData'][0]['authorizationToken']).decode().split(':')
    registry = token['authorizationData'][0]['proxyEndpoint']

    docker_client.login(
        username=username,
        password=password,
        registry=registry
    )

    client.pull(...)

leaves my docker daemon clueless of the login attempt. When i try to pull the same image via command line - I get the error 'no auth credentials'. What is even more weird that is when I login to ECR via command line I no longer have to authenticate via python script.

Any idea why is that happening?

I also encountered the same problem. While I don't have a solution to it, I did have a workaround/alternative that I have taken comfort with.

I ended up essentially simulating running commands on the command line via Python.

import base64
import boto3
import docker
import subprocess32 as subprocess

docker_client = docker.from_env()

# this loads AWS access token and secret from env and returns an ECR client
ecr_client = boto3.client('ecr', region_name='your-region')


def login_docker_client_to_aws_ecr():
    token = ecr_client.get_authorization_token()
    username, password = base64.b64decode(token['authorizationData'][0]['authorizationToken']).decode().split(':')
    registry = token['authorizationData'][0]['proxyEndpoint']

    # loggin in via the docker sdk doesnt work so we're gonna go with this workaround
    command = 'docker login -u %s -p %s %s' % (username, password, registry)

    p = subprocess.Popen([command], stdout=subprocess.PIPE, shell=True, bufsize=1)
    for line in iter(p.stdout.readline, b''):
        print line
    p.communicate()  # close p.stdout, wait for the subprocess to exit

I tried digging into the docker source code to take a crack at figuring out why this was happening but didn't get anything useful out of it:/

There's an open issue in the docker-py project about this, and one of their workarounds worked for me - stripping the leading https:// from the registry when performing the Docker login:

registry_url = token['authorizationData'][0]['proxyEndpoint'].replace("https://", "")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM