How to Build and push Docker images to AWS ECR with GitHub action
Back to Blog page

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.

Published by PJ

PJ Mar 6, 2023 4 min read

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:

  1. Install Docker on your local machine
  2. Have a project to create a docker image hosted on GitHub
  3. 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.

image-bd5151880c1e81a43d24ad29d7be4b838fd26333-1735x922-png
  • 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.

image-186f761d20beeea1bf98a72a14969360ca292e60-720x129-webp

  • 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>
image-35272a57d9417d1fa3719418b0d1d63a36902549-1878x738-png

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!

Tagged with:
Docker
Automation
AWS
5
0
Share
Enjoyed this article?
Leave a comment below!
Previous Article