Setting up CI/CD on a NodeJs Application To A Docker Environment Using Github Actions

Github Actions is an example of a simple and effective solution for Continuous Integration and Continuous Delivery, other examples of popular CICD tools are CircleCI, Jenkins, Gitlab CI, Azure DevOps, Bamboo, TravisCI.

The requirements for this setup are the NodeJs application to be deployed, a server as a hosting environment and also a Github account. 

Github Actions?

Github Actions is a continuous integration and continuous delivery that helps you automate, customize, and execute your software development workflows right in your repository. Github actions are event-driven, meaning that you can run a series of commands after a specified event has occurred. For example, every time someone creates a pull request for a repository, you can automatically run a command that executes a software testing script.

Getting Started

For our setup, we are trying to create a workflow file that builds our nodejs application, pushes the image to docker hub and also helps us deploy our application in a docker environment.

Step 1: Generating and Editing our workflow template

A default template can be generated for a nodejs application , click on the actions page, and some templates will be suggested automatically, but we are going to be making use of a custom template. To do this, select the set up a workflow yourself option to create a custom workflow file. There are two jobs in this workflow, the first job builds our application and also pushes the image to docker hub and the second job deploys our nodejs app.

Push Image to Docker Hub

Our workflow will be triggered when there is a push to the main branch.

The first job is named push_to_Docker_Hub. The job runs on a self-hosted server which we will discuss in detail  later. For our job we make use of node version 14.

The first action is actions/[email protected] This action checks out the repository so that the workflow file can access it.

The next action is docker/[email protected] , this is used to load the image. The image helps us to install emulators for architectures that are not supported originally so that you can run and build containers for any architecture.

The next thing is to login into docker hub with our credentials(credentials can be stored as environmental variables by going to the settings tab in github and selecting secrets, then you will be able to add your credentials as secrets) so our image can be saved in docker hub after building.

The next action is docker/[email protected], this builds our image using the dockerfile in our repository and when done saves the image to dockerhub.

At this stage our image has been successfully pushed to dockerhub.

Deploy NodeJs Application

This also runs on a self hosted server.

The action is appleboy/[email protected], this helps us to ssh into our instance with the required credentials. Then we run a script that stops and removes the container we want and also spins up a new container with the image we previously pushed to docker hub.

Then we commit our YAML file.

Step 2: Setting Up the Runner

We are done with our file configuration, we need to create a self-hosted runner to deploy our application. We go to the settings tab of the repository and select Actions on the left side. Click add runner, you can select the operating system and the architecture of the server you are trying to use. Then you login into your server or instance and copy the code in the Download and configure sections and paste it in the server command line.

The commands will download and extract the runner package into the directory actions-runner.

Now we can configure the runner.

You can input the name of the runner and the name of the work folder. 

To set the runner to listen actively for jobs, you can run the ./run.sh command and it’s also possible to set up the runner to run in the background.

To set up the runner in the background, enter into the actions-runner directory and execute the ./svc.sh script.