Create CI/CD pipeline for nodejs express with Gitlab

Eranga Dulshan
5 min readSep 6, 2020

--

CI/CD allows the developers to deliver the code more frequently and reliably. Implementation of CI/CD is known as the pipeline. Here we are going to build a simple pipeline for a nodejs express app with Gitlab to deploy to an ec2.

If you do not have an express app already, first create one. I am not going to describe creating an express app here. If you do not have any experience, this is a simple guide.

So now you have an express app. Then you need to add .gitlab-ci.yml file to your source folder. If we have this file, every time we push to gitlab upstream, the instructions within this file will be executed by a runner in gitlab.

.gitlab-ci.yml

Here is process of the simple pipeline that I am going to build in brief. When the code is pushed to a branch (called pre-prod), we will create a ssh connection with ec2 from the gitlab. Then we create a folder in the ec2 server and clone the project there. Then we use pm2 runner to run the express app. All these are executed using the created ssh connection.

Here is my .gitlab-ci.yml file.

Let’s see what are the options we have here. First we create a job (deployToAWS)(this is called a job). Then we define the stage. You can find more about stages here. Then using only, we define the branch that this job needs to be applied to. Then we have the before_script option to specify commands that needs to be run before the job gets started. What happens here is that we set configurations to initiate the ssh connection with the ec2. It is not different than how we initiate ssh connection from our pc (ssh -i path-to-pem user@ip). I also have set StrictHostKeyChecking to no. Because when the initial ssh connection happens with a server, it asks to add the host to known hosts. Then you give an input yes/no from your terminal. But this ssh connection initiates from the gitlab, there is no one to enter that input and press enter right. So we have set that to “no” by default. Here you also see a $PRIVATE_KEY term which is an environment variable. It is the key string inside .pem file which is used to access the ec2.

How does that environment variable come to the action. I will explain. In gitlab we can set up variables. In the gitlab project you can go to Settings -> CI/CD from the left panel. In that we have the environment variables section.

Here I have set up two variables. DEPLOY_SERVERS and PRIVATE_KEY. Here is my PRIVATE_KEY variable (value is the private key string from the .pem file).

Here is my DEPLOY_SERVERS variable. I have set the ip of the server that I am going to deploy the code to.

Okay, coming back to the .gitlab-ci.yml. Then we have the script section. There I have specified the path to a bash script which is on another file.

In the DEPLOY_SERVER section, I have set only one server. If you want multiple, you can add comma separated ip values there. So here I am initiating a ssh connection with each server (in this case only one). And run the script in the restart.sh.

Here is my restart.sh file.

This file contains the commands just to restart the server. That means we have to do some initial setup in the server. For that we have to login to the server by ourselves. There we clone the project initially, install npm modules and start the pm2 process (command - pm2 start app.js). If you run this for the first time, the pm2 process id will be 0. Why are we doing this for the first time is, then we do not have to specify those things in the restart.sh file. We can just do the restarting the server using the gitlab runner.

So in the restarting.sh script, first we delete the existing directory. Then do the cloning, go to the cloned directory, install node modules and restart the pm2 process (pm2 restart 0 - 0 means the process id which we took by running for the first time by logging to the server by ourselves earlier). And note that I have used a token before the @gitlab.com with the gitlab url. You can get such a token in Settings -> Repository. There you can create deploy tokens.

You will get a token upon creation and you can set the user name and token like following.

https://username:token@gitlab.com/******/*******.git

Why we use this is because we need to avoid additional setup or prompts for password during the execution of the script.

Now if you push to the specified branch (in the only section), a job will be started. You can see the jobs in CI/CD -> Jobs section.

That’s it. Now the server will be restarted in the ec2 with the updated changes every time you push to the specified branch only if the job was successful.

So folks, this is just a very simple CI/CD pipeline. You can add build, test and deployment stages in to the pipeline after this and see how we can benefit with the pipelines in different stages.

--

--