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.

Author Pirasanthan Jesugeevegan

Pirasanthan Jesugeevegan

Mar 8, 2023 • 5 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:

dockerfile
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 )

powershell
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

powershell
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.

Blog post image
  • 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

powershell
aws configure

Enter the access key and secret access key you got when you created a user.

Blog post image

  • Create ECR Repo

We will need to create an ECR Repo to add the docker images

powershell
aws ecr create-repository --repository-name <repo_name> --region <region_name>
Blog post image

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)

powershell
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.

powershell
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.

powershell
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

powershell
#!/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.

powershell
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

0

Enjoyed this article?

Leave a comment below!