How to automate pushing training docker image to ECR for SageMaker
Introduction
There are many times that you would prefer a custom docker image over what Sagemaker provides for you. People are using some tricks to install custom packages of their needs inside those default containers, but that is not clean nor reliable to do. Also, building a Docker image and pushing it to Elastic Container Registry is another kind of a problem. It has lots of steps and lots of commands to memorize to push the image to ECR every time you wanted to change something, adding a feature, or fixing a bug.
Amazon Web Services provides lots of tools to create and build infrastructures that made your life easier. With a combination of a git server (like Github), CodePipeline and CodeBuild you can automate the process of building a custom docker image and push it to ECR, and now you can get all of your focus on designing the model 🍻!
In this post I’m going to use GitHub as my git repository server but feel free to replace it with Bitbucket or Amazon CodeCommit service. The structure of the integration of these three systems is pictured below.
Elastic Container Registry
ECR is a private docker repository where one can push and pull its images to it. The ECR also has a public repository where anyone can download images with no authentication required. The policy access is available under permissions of a private repository which enables us to grant specific AWS accounts access or define wildcard access (which means anyone can have access) for pulling images.
To create a new ECR repository:
- Go to the AWS console
- Click on
Create repository
- Click on the view push commands to see commands to push to the repository of your interest.
CodePipeline
CodePipeLine act as an entry point of the structure. By pointing a new pipeline to a git repository and selecting a branch, the pipeline will subscribe to commits and code updates. Every time you push a new commit to the chosen branch of this repository, a web hook trigged the pipeline to pull changes and begin the process of building and pushing to ECR.
To begin with, you need to create a new pipeline from AWS console. Follow the config provided below and leave other configs with their default values.
Step 1
- PipeLine name: logical name referred to the name of our project.
- Service Role: choose New service role, so AWS create least privileged role for running pipeline.
- Role Name: the name of the role that AWS will create on behalf of you.
Step 2
- Source provider: choose the git repository service to connect to from the provided list.
- Repository name: your source repository.
- Branch name: branch of the repository to pair with.
CodeBuild
Step 3
In this step you can choose to connect to a created CodeBuild service or create a new one. In a CodeBuild service we define bash instructions to build and push our docker image from pulled source by CodePipeline service. The CodePipeline service is responsible for starting build process by calling the CodeBuild service.
Since we are creating new structure, we need to create new CodeBuild project for this repository by hitting the Create project button.
🚨 Region must be the same for all three service we are using in this architecture.
- Project name: logical name referred to the name of our project.
- Operating system: select Amazon Linux 2
- Runtime(s): select *standard*
- Image version: select Always use the latest for this runtime version
- Privileged: check the check box so we could be able to push to ECR.
- Service Role: choose New service role, so AWS create least privileged role for running pipeline.
- Role Name: the name of the role that AWS will create on behalf of you.
The buildspec.yml
file needs to be created, so CodeBuild can automatically build and push the image. To do this, simply replace the following commands in the scripts with the ones seen in ECR-view push commands:
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR and Docker Hub
build:
commands:
- echo Build started on `date`
- echo Builing image from docker file.
- docker build -t <YOUR REPOSITOR YNAME>:latest -f Dockerfile .
- echo Pushing image to Amazon ECR.
- aws ecr get-login-password --region eu-west-1 | docker login --username AWS --password-stdin <AWS ACCOUNT ID>.dkr.ecr.eu-west-1.amazonaws.com
- docker tag <YOUR REPOSITOR YNAME>:latest <YOUR ECR REPOSITORY PATH>:latest
- docker push <YOUR ECR REPOSITORY PATH>:latest
post_build:
commands:
- echo Build completed on `date`
Summary
In a nutshell, you will be able to autonomously generate machine learning model images with this architecture. This automation will bring you more stability of the codes and infrastructure because we eliminate the process of human interventions from pushing the image to the ECR. CodeBuild service builds and pushes the images from the ECR when we push a commit to the master branch. The trigger for this process occurs when commits are pushed to the master branch.