I want to pull a Docker image from a private repository and use it in my Elastic Beanstalk platform.
Short description
When you pull an image from a private repository, you might get the following error from your Elastic Beanstalk instance:
Error message from /var/log/ecs/ecs-agent.log[CannotPullContainerError] Error response from daemon: pull access denied for {username}/{repo}, repository does not exist or may require 'docker login': denied: requested access to the resource is denied" module=docker_client.go
This error occurs when there's an authentication gap between the private registry and Elastic Beanstalk. To use an image from a private repository, Elastic Beanstalk must authenticate with the online registry that hosts the private repository. It must authenticate before it retrieves and deploys your images from a private repository. There are two options to retrieve and store credentials for an Elastic Beanstalk environment to authenticate to a private repository:
- AWS Systems Manager (SSM) Parameter Store
- Dockerrun.aws.json file
Resolution
To retrieve a Docker image from a private repository using a Dockerrun.aws.json file, complete the following steps:
- Generate a valid authentication token
- Create an Amazon Simple Storage Service (Amazon S3) bucket and store the authentication file
- Create the Dockerrun.aws.json v2 file
Generate a valid authentication token
Note: If you receive errors when running AWS Command Line Interface (AWS CLI) commands, confirm that you're running a recent version of the AWS CLI.
-
Install Docker on your machine by running the following command:
$ brew install docker
-
Create an account on dockerhub.
-
Create a repository and transfer an image to the repository.
-
Run the Docker login command:
$ Docker login
-
Create a file named credentials.env by using the following command:
$ vi credentials.env
-
Add the following credentials to the preceding file created:
Note: Make sure to replace all example strings with your specified values and then save your file and exit editor mode.
DOCKER_USERNAME=example-user-name
DOCKER_PASSWORD=example-password
DOCKER_REGISTRY=https://index.docker.io/v1/
-
Run the following command:
docker run -it --rm \
-env-file=credentials.env \
v "$(pwd):/opt/data/" \
v "/var/run/docker.sock:/var/run/docker.sock" \
codeship/dockercfg-generator /opt/data/dockercfg
-
Retrieve the .dockercfg file:
$ cat /opt/data/dockercfg
Example output:
{
"https://index.docker.io/v1/ ": {
"auth": '**************************AMTE="
},
"HttpHeaders": {
"User-Agent": "Docker-Client/18.03.1-ce (linux)"
}
}
Note: Make sure to include the .dockercfg file in your application source bundle.
Create an Amazon S3 bucket and store the authentication file
Create a secure Amazon S3 bucket and transfer the .dockercfg file to the bucket. Make sure of the following:
- The Amazon S3 bucket is hosted in the same AWS Region as the environment that's using it. Elastic Beanstalk can't download files from an Amazon S3 bucket hosted in other Regions.
- Permissions are granted for the s****3:GetObject operation to the AWS Identity and Access Management (IAM) role in the instance profile.
Create the Dockerrun.aws.json v2 file
Create the Dockerrun.aws.json v2 file by running the following command and add the Amazon S3 bucket information under the authentication parameter:
- For the bucket parameter, add your Amazon S3 bucket information.
- For the image parameter, add your image name with the tag. This can be retrieved from your dockerhub account.
{
"AWSEBDockerrunVersion": 2,
"authentication": {
"bucket": "example-bucket-name",
"key": ".dockercfg"
},
"volumes": [
{
"name": "php-app",
"host": {
"sourcePath": "/var/app/current/php-app"
}
},
{
"name": "nginx-proxy-conf",
"host": {
"sourcePath": "/var/app/current/proxy/conf.d"
}
}
],
"containerDefinitions": [
{
"name": "php-app",
"image": "example-image-name",
"essential": true,
"memory": 128,
"mountPoints": [
{
"sourceVolume": "php-app",
"containerPath": "/var/www/html",
"readOnly": true
},
{
"sourceVolume": "awseb-logs-php-app",
"containerPath": "/var/log/sample-app"
}
]
},
{
"name": "nginx-proxy",
"image": "nginx",
"essential": true,
"memory": 128,
"portMappings": [
{
"hostPort": 80,
"containerPort": 80
}
],
"links": [
"php-app"
],
"mountPoints": [
{
"sourceVolume":"php-app",
"containerPath": "/var/www/html",
"readOnly": true
},
{
"sourceVolume": "awseb-logs-nginx-proxy",
"containerPath": "/var/log/nginx"
},
{
"sourceVolume": "nginx-proxy-conf",
"containerPath": "/etc/nginx/conf.d",
"readOnly": true
}
]
}
]
}
Note: The preceding command allows your Elastic Beanstalk instance to successfully authenticate with the online registry.
Related information
Using images from a private repository
Accessing private Docker images from AWS Elastic Beanstalk