How to Build and push Docker images to AWS ECR with GitHub action
In this article, we will be talking about docker (build, tag & push) to AWS ECR and how we can use it to speed up automation test runs.
In this article, we will be talking about docker (build, tag & push) to AWS ECR and how we can use it to speed up automation test runs.
Imagine if you had to build your docker image each time you trigger your automation run, this will take a longer time as the project may include many dependencies which means it may take a long time to install each dependency each time your trigger the run.
How to speed up your test run?
We need to make sure we have the latest docker image build before we trigger the test run.
How can we achieve this?
We can use a GitHub action to trigger on push to the master branch, this means that anytime you commit/merge your changes to the master branch we trigger an action.
In this case, we can trigger an action to build the docker image and push it to AWS ECR.
With this technique, when we run the automation test suit, we pull down the latest image from AWS ECR and run the test without any other actions.
Now for the fun part, let’s go create these scenarios in our project.
Prerequstion:
- Install Docker on your local machine
- Have a project to create a docker image hosted on GitHub
- You will need an AWS account
Dockerfile
Let’s open up a project from which you would like to build a docker image. In this example, I will be using a Cypress with Cucumber that I used for another article.
Create a Dockerfile at the root of your project, and the syntax should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM cypress/browsers:latest
RUN mkdir /web-ui-amt
WORKDIR /web-ui-amt
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm install
COPY . .
CMD [""]
# CMD ["npm", "cypress:run"] - to run test automatically when docker is running
In the above syntax, we are using Cypress's base image that has pre-loaded with the browsers and other software we will need to run cypress. We then create a directory inside of the image and copy the package.json file to that new directory so we can perform an npm install
. We can add commands to be triggered the test when the docker image starts up but I will leave it blank as I have.
Test your image:
We will be using the below code to build our docker image with the tag web-ui-amt:latest
with the file Dockerfile
in your root directory. ( if this command failed, it could be that you haven’t/didn’t install docker to your local machine )
1
docker build -t web-ui-amt:latest -f Dockerfile .
Once the docker is built, we can run it by the below code, We are starting to run the docker image with the command to run the test npm run cypress:run
1
docker run web-ui-amt:latest npm run cypress:run
Push Image to AWS ECR locally
First, you will need to log in to AWS and create a user with programmatic access to use AWS CLI if you don’t have one.
- Configuring AWS CLI
Once the user is created, you will need to configure AWS locally so that we can push the docker image to ECR with the right user. Type the below command in your terminal. If you get an error, you may need to install AWS
1
aws configure
Enter the access key and secret access key you got when you created a user.
- Create ECR Repo
We will need to create an ECR Repo to add the docker images
1
aws ecr create-repository --repository-name <repo_name> --region <region_name>
You can verify it by going to AWS -> ECR -> Resposities, you should see your repository name
- Push Docker Image to ECR
Retrieve an authentication token and authenticate your Docker client to your registry. Use the AWS CLI: (Privatekey can be found and extracted from the URL if you are inside the repository)
1
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <privateKey>.dkr.ecr.us-east-1.amazonaws.com
- Tag Docker Image for ECR Repo
This is the format of the syntax:docker tag <source_image_tag> <target_ecr_repo_uri>
below you can see my real example for this repo.
1
docker tag web-ui-amt-demo:latest 325398057325.dkr.ecr.us-east-1.amazonaws.com/web-ui-amt-demo:latest
- Push Image to ECR:
This is the format of the syntax:docker push <ecr-repo-uri>
below you can see my real example for this repo.
1
docker push 325398057325.dkr.ecr.us-east-1.amazonaws.com/web-ui-amt-demo:latest
Verify that the image is uploaded by going to AWS -> ECR -> Resposities -> Repository
Push Docker Image via Github Action
- Create shell script to trigger in GitHub action
Create a shell script in the root level called build-push.sh
and add the below syntax. The below code will build an image with the current revision, cashing from the latest image
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env bash
set -ex
ECR_PATH=325398057325.dkr.ecr.us-east-1.amazonaws.com
UI_RUNNER_DOCKER_IMAGE=${ECR_PATH}/web-ui-amt
UI_RUNNER_DOCKER_IMAGE_CACHE=${UI_RUNNER_DOCKER_IMAGE}:latest
UI_RUNNER_DOCKER_IMAGE_REV=${UI_RUNNER_DOCKER_IMAGE}:${GITHUB_SHA}
# Build image with current revision, caching from latest
docker pull -q ${UI_RUNNER_DOCKER_IMAGE_CACHE}
docker build \
--cache-from ${UI_RUNNER_DOCKER_IMAGE_CACHE} \
-t ${UI_RUNNER_DOCKER_IMAGE_REV} \
.
docker push -q ${UI_RUNNER_DOCKER_IMAGE_REV}
if [ $GITHUB_REF == "refs/heads/master" ]
then
docker tag ${UI_RUNNER_DOCKER_IMAGE_REV} ${UI_RUNNER_DOCKER_IMAGE_CACHE}
docker push -q ${UI_RUNNER_DOCKER_IMAGE_CACHE}
fi
- Create GitHub workflow
Create a file called ci.yml
inside .github/workflows
Then copy the below code into the ci.yml
file
The blow code will be triggered on push to the master branch, it will then log in to AWS with the provided Secrrits then it will trigger the shell script that contains build, tag & push commands.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
name: Docker Build & Push
on:
push:
branches: ['master']
jobs:
Docker:
name: Build Docker Image
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup AWS ECR Details
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{secrets.AWS_REGION}}
- name: Login to Amazon ECR
id: login-pf-aws-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build and push the tagged docker image to Amazon ECR
run: |
chmod +x build-push.sh
build-push.sh
- Add security to your GitHub repository
Last but not least, please add three secrets to GitHub.
Go to GitHub -> Resposiry -> Resposity settings -> secrets and variables -> New repository secret
Add the below secret with the name and value:
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_REGION
Push the changes to GitHub and you should see the GitHub action get triggered on the Action section within your repository. Once it's finished you should also see your latest image on AWS ECR
Link to GitHub repo
If you enjoyed this article, please click the 👍 button and share to help others find it!