Automate Docker CI/CD Pipelines with GitHub Actions
In today’s fast-paced development environment, continuous integration and continuous deployment (CI/CD) are no longer optional—they’re essential. Automating these processes not only speeds up your workflow but also minimizes human error, allowing you to focus on what truly matters: writing quality code.
If you’re leveraging Docker for your applications, integrating it with a CI/CD pipeline using GitHub Actions is a game-changer. In this guide, we’ll walk you through the steps to automate your Docker CI/CD process, ensuring a seamless deployment every time.
For this demonstration, we’ll use a simple Python application, which you can find at this GitHub repository.
Create Docker Repository
First, create a Docker repository to store your application images. This can be done on Docker Hub.
Create a new repository on Docker Hub under your namespace. Name it appropriately and set its visibility to public or private based on your needs.
- Namespace: sauravm
- Repository Name: demo-cicd
- Short Description: CI/CD Demo
- Visibility: Public (Set the repository visibility to public or private based on your needs)
Generate Personal Access Token
To allow GitHub Actions to access your Docker repository, generate a personal access token. This token will be used for authentication instead of your Docker password, providing better security and flexibility.
- Access token description: demo-cicd
- Access permissions: Read & Write
Local Image Build and Push
Before automating the process, build and push the Docker image manually to ensure everything is set up correctly:
docker login -u sauravm
# Enter the generated access token for Password
# Ensure you are in the root directory where Dockerfile is present
docker build -t sauravm/demo-cicd:manualBuild_v1 .
# Test the image build
# docker run -d -p 5000:5000 sauravm/demo-cicd:manualBuild_v1
# Push the application image to Docker Hub
docker push sauravm/demo-cicd:manualBuild_v1
Once everything is set up properly, automate the Docker build to trigger whenever the application code changes. Use GitHub Actions to push the latest Docker image to Docker Hub automatically.
Setup GitHub Actions Workflow
Create a .github/workflows/ci.yml
file in your repository. Define the workflow to trigger on code pushes. Use actions to check out the code, log in to Docker Hub, and build and push the Docker image.
Github Actions Workflow (ci.yml)
name: CI
on:
push:
jobs:
build:
name: Build and Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: $\{\{ secrets.DOCKERHUB_USERNAME }}
password: $\{\{ secrets.DOCKERHUB_TOKEN }}
- name: Build and Push Docker image to Repository
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
$\{\{ secrets.DOCKERHUB_USERNAME }}/demo:latest
$\{\{ secrets.DOCKERHUB_USERNAME }}/demo:$\{\{ github.sha }}
GitHub Secrets
Store your Docker Hub credentials as GitHub Secrets in your GitHub repository settings to keep them secure. In your GitHub repository, go to Settings > Secrets and variables > Actions. Add New Repository Secrets: Add
and DOCKERHUB_USERNAME
with your DockerHub credentials. Use these secrets in your workflow to log in to Docker Hub and push images.DOCKERHUB_TOKEN
Automating Kubernetes Deployment
Enhance your CI/CD pipeline by extending your GitHub Actions workflow to automatically update your Kubernetes deployment with the latest Docker image. This can be achieved by committing changes to a dedicated code deployment repository monitored by Argo CD, or by utilizing the
tool, which will ensure your Kubernetes cluster is updated seamlessly.kubectl
Github Pre-requisite
To get started, follow these steps:
- Create a Deployment Repository: https://github.com/sarubhai/demo_cd
- Generate a Github Personal Access Token
Navigate to Settings -> Developer settings -> Personal access tokens -> Fine-grained tokens -> Generate new token
Configure the token as follows:
- Token name: demo-cicd-pat
- Expiration: 90 days
- Description: Demo CI/CD Personal Access Token
- Repository access: Only select repositories, e.g. demo-ci, demo_cd
- Permissions:
Repository Permissions:
Contents: Read and write
Metadata: Read-only
Pull requests: Read and write
Argo CD Pre-requisite
Set up Argo CD to automatically sync and deploy resources from your GitHub repository to your Kubernetes cluster. Create an Application in Argo CD with the following configuration:
- Application Name: backend-api
- Project Name: default
- Sync Policy: Automatic
- Prune Resources: True
- Source Repository URL: https://github.com/sarubhai/demo_cd.git
- Source Revision: main
- Source Path: kubernetes
- Destination Cluster URL: https://kubernetes.default.svc
- Destination Namespace: default
New Github Actions Workflow (ci-cd.yml)
name: CI/CD
on:
push:
branches:
- main
jobs:
build:
name: Build and Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: $\{\{ secrets.DOCKERHUB_USERNAME }}
password: $\{\{ secrets.DOCKERHUB_TOKEN }}
- name: Build and Push Docker image to Repository
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
$\{\{ secrets.DOCKERHUB_USERNAME }}/demo-cicd:latest
$\{\{ secrets.DOCKERHUB_USERNAME }}/demo-cicd:$\{\{ github.sha }}
- name: Checkout Deployment Repository
uses: actions/checkout@v4
with:
repository: sarubhai/demo_cd
token: $\{\{ secrets.GH_PAT }}
path: deploy-repo
- name: Modify deployment.yml with the latest image
working-directory: deploy-repo
run: |
# Remove Topics.csv from remote repo
IMAGE_TAG="$\{\{ secrets.DOCKERHUB_USERNAME }}/demo-cicd:$\{\{ github.sha }}"
sed -i "s|image:.*|image: ${IMAGE_TAG}|g" kubernetes/deployment.yaml
# Commit changes to Deployment Repository
git config --local user.name "GitHub Action"
git config --local user.email "action@github.com"
dt=$(date '+%Y-%m-%d')
git add -A
git commit -m "Automated Deployment- $dt"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: $\{\{ secrets.GH_PAT }}
path: deploy-repo
branch: feature-new-deployment-config
- name: Merge Pull Request
working-directory: deploy-repo
run: |
git merge feature-new-deployment-config
git push -u origin main
git branch -d feature-new-deployment-config
git push --delete origin feature-new-deployment-config
This workflow ensures that every time code is pushed to the
branch of code repository, your Docker image is built and pushed to Docker Hub. It then automatically updates the Kubernetes deployment configuration with the new image tag, creates a pull request to merge these changes into the main
repository, and syncs them with your Kubernetes cluster through Argo CD.deployment
By following these steps, you can create a robust CI/CD pipeline that automates your Docker builds and deployments, ensuring your applications are deployed quickly and reliably, minimizing downtime and maximizing productivity.
Automating your Docker CI/CD pipeline with GitHub Actions is a powerful way to enhance your development process. It not only saves time but also ensures that your application is always in a deployable state. As you grow more comfortable with GitHub Actions, you’ll find it’s easy to tailor workflows to your exact needs, making your CI/CD pipeline as efficient as possible.