The world’s leading publication for data science, AI, and ML professionals.

Node.JS DevOps: Simplify Your Life with GitHub Actions

Ho to package and deploy a node.js app and release to npmjs, docker hub and potentially to every other target

Who has read my articles knows my vision about the future of DevOps and cloud adoption (just DevOps is dead, long life to NoOps to mention one). To explain it without losing myself in out of scope though, I believe in automation and getting ready to go solutions (cloud, tools, etc.) that make us focus on application only. This approach leads developers to a sustainable approach and

we should always find an automated way for deployments that comes for free with limited effort.

In this article, I will share with you the configuration that I have adopted for deploying MESS (MongoDB Event Sourcing System), my first Node.js opensource project. The configuration is a single YAML file that unlocks infinite powers to your GitHub repository.

What I realized here is a simple configuration that satisfies all the basic needs of a nowadays enterprise application:

  • automatically version code
  • run test on every release
  • publish artefact to NPMJS (in case you have a library or you are delivering through NPM)
  • publish your docker container ready to go to a container repository

All these features may seem hard to be reached, but you will discover that will come more or less out of the box using GitHub actions. This guide will explain the tricks in few simple steps:

  1. creating a simple node.js application
  2. Adding a workflow with GitHub Action
  3. Auto-tagging the source code using Semver
  4. Pushing on NPM.js on each commit
  5. Pushing on Docker Hub on each commit

Let’s see how it is easy!

Photo by Thomas Bishop on Unsplash
Photo by Thomas Bishop on Unsplash

Creating a simple node.js application

It’s clear that we need something to deploy before starting the cool part of the tutorial. To do so, we need just a simple node.js application. The first step is to create a new one using npm CLI.

npm init 
npm install express --save

The command above init the node application and install express as a web server. For demo purposes, we can just create an app with some dummy endpoints. Create a file named main.js with the following content:

Now you can alter the npm package by entering the definition of the run command. In the next example, I used supervisor for having hot reload on dev environment and regular node for the production.

Type npm run serve for seeing your app live.


Adding a workflow with GitHub Action

Once we have a dummy application to test, we have to commit it to a public or private GitHub repo. This step should be quite easy for all developers so I won’t waste time explaining it 😃

Once the code is pushed, you can open the GitHub pages and click on "Action", then click on the "New Workflow" button as in the next image.

Create a new workflow
Create a new workflow

This will ask what template use, in our case we will choose the node.js one, but this won’t exclude do access to all other action available.

Selecting the right template
Selecting the right template

Now we are ready for setting up the workflow!


Auto-tagging the source code using Semver

First of all few words about SemVer for those who are not used to it. SemVer is a semantic versioning numbering system that, in simple words, compute the version of a software basing on the commit history. In an example, it increases the patch number (1.0.x) on each commit or increments the minor version (1.X.0) each time you merge a feature branch on the master. As you can imagine you can adapt the convention to meet your numbering requirements.

To enable the automatic versioning you just need to add the following steps:

As you can see in the code there are two different steps. The first one enables the plugin for managing semver tagging, the second one simply displays it to the console. The trick here is to add an id for the first step, this will allow you to use the output variable like ${{steps.version-bump.outputs.newTag}} . At this point, we have the versioning done. Yes, because this package tags each commit and change the package.json version attribute automatically.

Well, now it’s time to push our code to NPM!


Pushing on NPM.js on each commit

The push step on NPM is quite easy. The first step is to add a Secret value with the NPM token that you can get from your profile on NPM. The Secret section is available on GitHub under the "Settings" tab on your repo. In the next image, you will see the NPM_TOKEN and the other settings that we will use for docker support.

GitHub Secrets
GitHub Secrets

Now we can add the following configuration to the workflow:

This step uses the information on the package.json file for testing and publishing the code on NPM. That’s all! Just jump to the next section to publishing our code to docker also.


Pushing on Docker Hub on each commit

The first step for enabling the deployment on docker is to create a Docker image to commit. To do so, just add a Dockerfile with the following content:

ROM node:alpine as builder 
WORKDIR /usr/src/app 
COPY ./ /usr/src/app 
RUN npm install  
FROM node:alpine as app 
WORKDIR /usr/src/app C
OPY --from=builder /usr/src/app /usr/src/app 
ENTRYPOINT ["/bin/sh", "-c" , "pwd & ls & npm run serve"]

To build and publish the Docker image you have just to add another piece of code into the workflow YAML. The next one is enough:

The YAML performs the steps: login, get info for the image, build & publish. The variables DOCKER_USERNAME,DOCKER_PASSWORD are GitHub secret. For security, you can use an auth token instead of a password. This can be generated by your Docker Hub account profile. In this example I use a double tag: I tag with "latest" each image and I add a tag based on the Semver. The Trick is done by adding two labels on the same image with the setting:

tags: zeppaman/mongo-event-sourcing:latest, zeppaman/mongo-event-sourcing:${{ steps.version-bump.outputs.newTag }}

As you can see, I used the output variable from the tagging steps. Now all the configuration is completed and we have the pipeline set. Easy, right?


What to take home

GitHub action is a very easy tool for implementing a build pipeline. The setup easily integrates with NPM and Docker and this enables your application to be easily consumed by all the platform that is based on containers. I’m referring to Kubernetes and to the other cloud platforms. Moreover, you can also deploy by npm for sharing the library or for allowing customization of your application.

That’s why I chose this setup for my open-source app and I easily find a setup that could help users to adopt it smoothly.


Loved the article? Become a Medium member to continue learning without limits. I’ll receive a portion of your membership fee if you use the following link, with no extra cost to you.

References


Related Articles