CI/CD pipeline to Automate Docker-image build with GitHub Actions

ANTONY A N
6 min readMar 8, 2023

--

Whenever you are working on a product you have to ensure that it performs well in the development and test environment before pushing it into a production environment.

What will be the case of a docker application? you have to ensure the container works fine with every change in the application. It can be checked by running containers with updated docker images.

But it is a hectic task to create the new images manually based on the changes that we have made in the application, right?

In this example, we are automating the process using Github actions, whenever you are making an update in your git repo a docker image will be built in the build server and a docker container will be created in the test server by triggering GitHub action.

So let’s start.

We are creating a GitHub repository for this project and our repository contains the following files in it.

  • Dockerfile
  • app.py
  • requirement.txt

Our sample repository contains a basic flask application.

You can refer to the files here

The Docker file contains the instructions to create our docker image.

app.py is our sample application which prints “hello world app”.

requirement.txt refers to the modules required for our application.

Once you have created the required files in your repository, we can proceed to set up our GitHub actions.

Inside your repo, you can find an option “actions

Now you will be able to view the following image.

Since we need to create a docker image, select the “Docker image “ and click configure.

You can see that a new file is created inside your repository.

This is a default workflow, now we are making our required changes in this file.

We need to set up our pipeline in the following way.

  • When there is a commit to the master branch, we need the actions triggered.
  • In the dev environment, a docker image should be created based on the latest changes and need to push the image to the docker hub.
  • In the test environment, a docker container should be created from the latest image from the docker hub.

So let’s create the following workflow based on this requirement.

name: Docker Image build

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:
name: Build Docker image and push to repositories
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: login to hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: antonyanlinux/myapp:latest

- name: deploying
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
password: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
docker image pull antonyanlinux/myapp:latest
docker container stop my-container
docker container rm my-container
docker container run -d --name my-container -p 80:5000 antonyanlinux/myapp

Let’s have a deeper look at the code.

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

Whenever a push/pull request occurs on the master branch, it will be triggered.

In the next step, we are specifying the following actions.

  • runs-on: ubuntu-latest denotes that we are performing the image build action in a virtual environment based on ubuntu latest.

In our job section, we are using some actions for our workflow.

  • actions/checkout@v3 It is an official GitHub Action used to check out a repository so a workflow can access it.
  • docker/login-action@v2 we need to push our images to images to docker hub, it can be done with help of this action.

In this action, we need to authenticate the docker hub with our username and password, we are passing these values using the secret option, and we will later check how to add secrets to GitHub.

  • docker/build-push-action@v4 this action will create a docker image based on the Dockerfile and it will be pushed to our docker hub account.

Now the latest image is pushed to our docker hub account. We need to check the output by running a docker container based on the image that we have pushed into the docker hub.

So we are setting a test server with docker installed and we have added ec2-user to the docker group.

Also, we have enabled password authentication for the server and the login details such as username, password, hostname are stored as secrets.

  • appleboy/ssh-action@v0.1.8 this action will be performing ssh actions and creating the docker container, the commands are mentioned in the script section.

After making the changes commit the file.

That’s it, We need to add certain secrets here, for that clock on settings >> secrets and variables>> action

You will be directed to the following interface,

Click on create new repository secret, and add the secrets.

  • docker hub username
  • docker hub password
  • The IP address of the test server
  • ssh user
  • ssh port
  • ssh password

We are setting up the test server in amazon Linux, so our ssh user will be ec2-user.

once you have added the secrets, it will look like the following.

Now let’s check our workflow, we are making a change in our application and updating it to version 2.

If we check the actions tab, we can see that our workflow is running.

If we click on the workflow we can see that it executed successfully.

Now let’s have a check on our container, it is running at port 80 of our test server.

Yes, It changed to version 1 to version 2, Let’s update the version to 3.

Now the pipeline triggered and it started executing.

It is completed now,

Let’s check on our container,

It updated to version 3 now.

That’s it, we have successfully created the pipeline.

In this article, we have checked how to automate the Docker image build process on every commit on the Git repo using GitHub actions.

By following this automation process we can save time and can ensure that every change that we are committing is reflected in the docker container.

Thank you for reading :)

--

--