Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 618
Łukasz Avatar asked Nov 07 '22 23:11

Łukasz


2 Answers

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 :/

like image 55
Prateek Madhikar Avatar answered Nov 14 '22 22:11

Prateek Madhikar


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://", "")
like image 38
Jason Peacock Avatar answered Nov 14 '22 22:11

Jason Peacock