Efficient Docker Image Caching and Deployment with GitHub Actions and Amazon ECR

May 12, 2024

Introduction

In this blog post, we'll explore how to leverage GitHub Actions to build and push Docker images to Amazon Elastic Container Registry (ECR), enabling efficient caching and deployment of your containerized applications.

AWS ECR is a fully-managed Docker container registry that makes it easy to store, manage, and deploy Docker container images. By integrating GitHub Actions with ECR, you can automate the process of building, tagging, and pushing your Docker images, ensuring that your application deployments are streamlined and reliable.

Leveraging Remote Cache Support in Amazon ECR

As mentioned in the AWS blog post, AWS has announced remote cache support in Amazon ECR for BuildKit clients. This feature allows you to store a remote build cache in Amazon ECR, which can be used to speed up your container builds.

To take advantage of this feature, you can update your GitHub Actions workflow to use the docker/build-push-action@v5 action, which includes support for the cache-from and cache-to options:

Introduction

This tutorial will guide you through the process of setting up a GitHub Actions workflow to build Docker images, utilize remote caching, and deploy these images to Amazon Elastic Container Registry (ECR). By leveraging ECR's newly announced remote cache support, developers can significantly speed up the build process of Docker images in CI/CD pipelines.

Prerequisites

Before beginning this tutorial, ensure you have the following: - An AWS Account. - Familiarity with Docker and GitHub Actions. - Basic knowledge of Terraform for infrastructure setup (optional but recommended).

Step 1: Set Up Your AWS Environment

Firstly, you need to prepare your AWS environment to support the integration with GitHub Actions:

Terraform Configuration

If you are using Terraform, use the provided code snippet to create the necessary AWS resources, including the OIDC provider and ECR repository. Here's a brief on each block:

Apply this configuration by running:

cd terraform
terraform init
terraform apply

Ensure you review and approve the resources that will be created.

Step 2: Configure GitHub Repository Secrets

To securely interact with AWS from GitHub Actions, configure the following secrets in your GitHub repository:

These credentials will be used by GitHub Actions to authenticate against AWS services.

Step 3: Create the GitHub Actions Workflow

Create a .github/workflows/docker-build.yml file in your repository and define the workflow as follows:

Workflow Definition

name: Build and Push to ECR with Remote Cache

on:
  push:
    branches:
      - main

env:
  AWS_REGION: eu-central-1 # Replace with your desired AWS region
  REPO_NAME: my-simple-app # Replace with your desired ecr repository name

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Git Clone the Repository
        uses: actions/checkout@v3

      - name: Configure AWS Credentials
        id: configure-aws-credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/GitHubAction-AssumeRoleWithAction
          role-session-name: GitHub_to_AWS_via_FederatedOIDC
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Create and use a new builder instance
        run: |
          docker buildx create --name mybuilder --use

      - name: Build and push
        uses: docker/build-push-action@v5
        id: build-prod-backend-image
        with:
          context: .
          push: true
          tags: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.REPO_NAME }}:${{ github.sha }}
          builder: mybuilder
          cache-from: type=registry,ref=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.REPO_NAME }}:cache
          cache-to: type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ref=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.${{ env.AWS_REGION }}.amazonaws.com/${{ env.REPO_NAME }}:cache

In this updated workflow, we:

  1. Set up Docker Buildx, which is required for the remote cache feature.
  2. Create a new builder instance named mybuilder and use it for the build.
  3. Use the docker/build-push-action@v5 action to build and push the Docker image.
  4. Specify the cache-from and cache-to options to leverage the remote cache in Amazon ECR.

The cache-from option tells the builder to use the remote cache stored in the specified ECR repository, while the cache-to option instructs the builder to export the cache to the same ECR repository.

By using this approach, your GitHub Actions workflow will benefit from faster build times, as the remote cache in Amazon ECR will be used to speed up the build process.

For caching docker image in Github cache check:

Explanation of Key Steps

Conclusion

By following these steps, you've automated the process of building and deploying Docker images using GitHub Actions with caching to Amazon ECR. This setup not only simplifies the deployment process but also reduces build times significantly through the use of remote caches.

For further reading on Docker image caching and GitHub Actions, explore the additional resources linked in this post. These resources provide deeper insights into CI/CD optimizations and advanced configurations.

Feel free to clone the accompanying GitHub Repository to see a working example of the configurations discussed in this tutorial.

Additional Resources