How to CI and CD a Node.JS Application Using GitHub Actions

Learn how to CI/CD with GitHub Actions and Docker

Photo by Jannes Glas on Unsplash

This article will cover the following:

Use Docker instead of bare metal deployment

Use GitHub actions for continuous integration of your app

Use GitHub actions for continuous deployment by pushing the Docker image to a Docker registry (Docker Hub)

Our workflow will look like this

A workflow of a Node.js app deployed using GitHub actions

The complete source code is available on GitHub

Tip: Optimize teamwork by using the right tools for code-sharing

Use Bit to share, install and collaborate on individual JS Modules and UI components. Stop wasting time configuring packages, managing multiple repositories or maintaining cumbersome monorepos.

Components with Bit: Easily share across projects as a team

Use Docker instead of bare metal deployment

Dockerizing an existing app is easy. All we need is a Dockerfile and an optional .dockerignore file. Below is a Dockerfile for our app.

Dockerfile for Node.js express app

It copies our package.json, runs npm install and starts the server. To make sure our file is correct, we can run docker build -t abhinavdhasmana/github-action-example-node . from the root folder. If we run docker images , we will see our latest image. We can also run our container with docker run -d -p 3000:3000 abhinavdhasmana/github-action-example-node . Point the browser to http://localhost:3000/ and text will appear.

What are GitHub Actions and how do they work

‘GitHub Actions’ is an API that can react to any event, GitHub’s or our own events. For example, for every push event on the repository, we want our test cases to run.

For GitHub Actions to work, we need to create a .github/workflows folder. We need to create our workflows inside this folder. Let’s create push.yml . Here is what we want from our workflow:

On every push, perform these actions in the given order

git clone the repo run npm install run npm lint run npm test build the docker image login to docker hub Push the image to docker hub

Since we have to run each of these commands inside a docker we have to declare a Dockerfile for each of these actions and run the command in those containers. This is, of course, very tedious and error-prone. Remember, GitHub Actions are code, so we can just reuse, edit and fork them as we do with any other piece of code.

This is how our push.yml would look like

GitHub actions file for npm actions and push to docker hub

Let’s dissect this file

line 1: We want to trigger our workflow when someone pushes the code to our repo

line 3–6: We are defining a job build-and-publish which runs on ubuntu-latest . Each job runs in a fresh instance of a virtual environment. A job can contain one or more steps .

line 8: This is step 1 of our application. Here we want to get our source code. We can write our own code to pull our source code or reuse an open source. The repo link is https://github.com/actions/checkout

line 9-12: This is step 2 of our workflow where we run npm install on our codebase. Again, we use an open source action at https://github.com/actions/npm and pass install as an argument.

line 13–20: These are same as the last step except the argument passed to npm command.

line 21–24: We build a docker image of our code with the help of docker action and tag the image as abhinavdhasmana/github-action-example-node

line 25-29: This one is a little different where we want to login into docker hub. Here we use secrets which are passed as an env variables to our build. We can set these env variables in many ways. To set this up via GitHub, go to Settings-> Secrets and create new secrets

Store secrets in GitHub

line 30-33: We push the image to the docker hub with the tag we created in line 24.

If we commit these changes, GitHub Actions will come into play and start running all the steps in our job. We should see something like this

GitHub Actions running our job

To validate if a new image has been pushed to DockerHub, we should see a new image being pushed in Docker Hub

Docker Hub image

Full source code is available on GitHub.

Learn More