Automating Docker Builds and Deployments with GitHub Actions

Introduction

As part of my DevOps journey, I have successfully set up a CI/CD pipeline using GitHub Actions to automate the building, pushing, and deploying of Docker images to AWS. This workflow enables automatic deployment to staging and production environments based on GitHub branches.

This article covers the step-by-step process of:

  1. Setting up GitHub Actions for Docker builds

  2. Configuring AWS credentials for ECR

  3. Deploying to staging and production environments

  4. Using GitHub Environments for controlled deployments

  5. Sending Slack notifications for workflow status updates

Let’s get right into it.


Prerequisites

Before setting up the CI/CD pipeline, ensure you have the following:

  • An AWS account with permissions to create and manage ECR, EC2, and IAM roles.

  • A GitHub repository with the project files

  • AWS credentials stored as GitHub secrets (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY).

  • A running EC2 instance with Docker installed for deployments.

  • An Amazon ECR repository created to store Docker images.

  • Slack webhook URL stored as a GitHub secret (SLACK_WEBHOOK_URL) for notifications.

Setting Up GitHub Actions for Docker Builds

The first step in the pipeline was to automate the process of building and pushing Docker images to Amazon Elastic Container Registry (ECR). Below is the GitHub Actions workflow that handles this process:

name: Build and Push Docker Images to ECR

on:
  workflow_dispatch: # Allow manual triggers

jobs:
  build-and-push:
    runs-on: ubuntu-latest  
    strategy:
      matrix:
        service: [frontend, backend]  # Parallel builds for frontend & backend

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4  

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

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

      - name: Define image tags
        run: |
          echo "ECR_REGISTRY=${{ steps.login-ecr.outputs.registry }}" >> $GITHUB_ENV
          echo "IMAGE_NAME=${{ steps.login-ecr.outputs.registry }}/name-${{ matrix.service }}:latest" >> $GITHUB_ENV

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

      - name: Build and push Docker image
        run: |
          docker buildx build --push -t $IMAGE_NAME ./${{ matrix.service }}

      - name: Send Slack Notification
        if: always()
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_MESSAGE: "Docker build and push for ${{ matrix.service }} completed."

Step-by-Step Breakdown of the Workflow

  1. Triggers manually.

    You can equally set it to trigger on push to main or development.

  2. Checks out the repository

    • Uses actions/checkout@v4 to pull the latest code from GitHub.
  3. Configures AWS credentials

    • Uses aws-actions/configure-aws-credentials@v3 to authenticate with AWS.
  4. Logs into Amazon ECR

    • Retrieves an authentication token and logs in to ECR for Docker push.
  5. Builds and pushes the Docker image

    • The image is tagged with github.sha, ensuring unique versions.
  6. Sends Slack notification

    • If the workflow succeeds or fails, a Slack message is sent.

Conclusion

With this setup, we have successfully automated the building and pushing of Docker images to Amazon ECR using GitHub Actions. This process ensures that every code change pushed to the development or main branch triggers a reliable and repeatable build process.

By integrating AWS authentication, Docker image tagging, and Slack notifications, we now have a streamlined workflow that improves efficiency and reduces manual intervention.

The next step is to extend this pipeline to deploy the built images to staging and production environments, ensuring a complete CI/CD process from code to deployment. We will do that in forthcoming episodes. Thank