I was looking for a tutorial on how to deploy a Node.js application from a GitLab repo with GitLab CI/CD, but couldn’t find one specifically for Node.js. So here is my attempt to write one for future reference and for those who seek for the same information.
Having spent some time on GitLab documents, it’s actually pretty straight forward. GitLab already has documentations on deploying Python and Ruby applications using GitLab CI/CD, which makes the job super easy as it’s almost identical.
The example below is available at https://gitlab.com/seulkiro/node-heroku-dpl/.
Before anything, let’s create a GitLab project then check out the repo from it.
You can create a project by clicking the New project button. This GitLab document illustrates exactly how to do so. Below is my example of creating a GitLab repo. You would need to replace the repo URL (highlighted in bold and italic) with your project repo URL.
Don’t worry about the warning. It will disappear once you make first commit.
Now, add README and .gitignore files to the project.
Node.js Express App
With the initial project setup, we are ready to create our Node.js app. I am going to create an Express app as an example.
Create a brand new project and install express.
It will ask a bunch of questions for the project setup without -y. I am using defaults here by adding -y. You can change these options later by modifying the package.json file.
Now, create the entry point of the app by adding the following to index.js in the project’s root directory.
The above is a super simple Node.js app defining a route that responds to a GET request to / with a JSON object.
Let’s run this and see how it works locally.
Open your browser and go to http://localhost:5000/. You should see the following hello world JSON object.
Heroku Application Setup
Now, let’s create a Heroku application. This will be the application or environment to which we are going to deploy our Node.js application with GitLab CI/CD.
It can be easily created from the Heroku dashboard. All you need is the app name. Note down your app name. It will be used in the GitLab CI/CD configuration file to specify which Heroku app you want to deploy to.
There is one more thing we need to take care of before setting up GitLab CI/CD. We need to tell Heroku which version of Node.js and NPM it should use when our little Node.js app is deployed.
We can do this by modifying the package.json file. Let’s update the file by adding the engines and scripts sections just like below.
The engines section tells Heroku to use specific versions of Node and NPM for the app. Heroku uses NPM to start the app. So running the app needs to be reflected in the scripts section. Modify the default scripts section so that npm start will kick off our app.
After this change, you can run the app by the following command.
GitLab CI/CD Configuration File
We are almost there.
We need to create a GitLab CI/CD configuration file in the project’s root directory, which is used by GitLab runner to manage jobs as part of CI/CD, e.g. test, deploying to staging or production environments.
Add the following to .gitlab-ci.yml.
The YAML file basically tells GitLab to use Node.js docker runner to deploy the app to Hoerku on every push. And shell scripts defined under script will be executed by the runner.
Note the last shell script. It uses dpl, continuous deployment deploy tool, to deploy our app to Heroku. The provider option specifies the provider that we want to deploy to, i.e. Heroku in our case here. The app option sets the Heroku app name. Remember the Heroku app? You need to substitute your Heroku app name here.
Finally, the api-key option sets the Heroku API key. It is not a good practice to include the API key in the file directly. GitLab provides a way to store it in a protected way.
Go to your GitLab project. And Settings > CI/CD > Secret Variables is the place where you can store your Heroku API KEY or any other environment variables that the Runner can access to. These variables can be accessed by $ENVIRONMENT_VARIABLE in the YAML file, i.e. .gitlab-ci.yml.
By the way, the Heroku API key is found in the account settings.
We are all set for deployment.
Two more things though. A while back when we created our Node.js app and installed Express, it installed a bunch of dependencies under the node_modules directory. We don’t want to push them to our repo. We can ignore them by adding it to .gitignore file.
In addition, in order to make CI/CD to happen on push, shared runners should be enabled in the project’s settings, Settings > CI/CD > Runners settings, unless you plan to use your own runners.
Let’s commit and push all of our changes.
The push should kick off deployment to Heroku. The GitLab project overview will indicate that there is an active deployment with an orange pause icon.
Clicking the orange pause button should take you to the pipeline. You should be able to see the logs.
The deployment should succeed shortly after. Note that shared runners may not pick up your deployment if it’s not available.
Now, check out the Heroku dashboard. The app should be deployed.
You should be able to open the app by clicking the Open app button.
GitLab CI/CD is super easy to set up and useful for deploying your changes to different staging environments before production then finally production environment.
Though I didn’t talk about testing in this post, it would be another great thing about CI/CD because you can test your changes before any deployment. Failure would stop the deployment flow entirely, and you would get notified for it too!
Heroku supports git repo and even deployments from GitHub out of the box. But I think it’s hard to beat GitLab and Heroku combo which provide unlimited private project, issue tracking, CI/CD, wiki, etc for testing our your ideas and small side projects.
That’s it. Hope you enjoy the post.