A hitchhikers guide to Node JS deployments
Tags: node, webdev, devops
Published: 2021-02-16 21:19:13

Yet another JavaScript framework...?

Joy! Now, how do you deploy it? 

As a co-founder of [Cleavr.io](https://cleavr.io) a service that helps deploy your web apps, I wanted to conduct some due-diligence around several back-end NodeJS frameworks. My objective was to understand how easy, or difficult, they are to deploy to production on a virtual private server, using our service. 

This article goes over some of my findings, high level observations, and musings of the several frameworks I investigated.

What this article is NOT, is a suggestion or opinion piece on what frameworks are better than others or which one you should use. It's simply a guide, of sorts, of what you might look out for when deploying one of these frameworks. 

## The frameworks

These are the frameworks I looked at for this effort - 

- [Adonis](https://adonisjs.com/)
- [Hapi](https://hapi.dev/)
- [Express](https://expressjs.com/)
- [Koa](https://koajs.com/)
- [Sails](https://sailsjs.com/)
- [Meteor](https://www.meteor.com/)
- [Total](https://www.totaljs.com/)
- [Nest](https://nestjs.com/)
- [Loopback](https://loopback.io/)
- [Foal](https://foalts.org/)

## The criteria

My evaluation included the following - 

- Does the documentation help me figure out how to deploy the framework for production? 
- Is the documentation easy to navigate and easy to locate what I'm looking for? 
- Does the framework provide either a quick start guide or easily accessible sample apps that I can spin up and deploy? 
- Was the deployment process straightforward? 
- Did I have to do anything unexpected for the deployment to be successful? 

---

## The results

### Documentation

To be honest, it was surprising to see how the majority of frameworks have very little documentation around making their framework production ready and/or how to deploy. 

Express, Sails, LoopBack, and Meteor did the best to provide some guidance around the subject. The others were noticeably missing information. 

Meteor was the first framework I targeted and, initially, I was annoyed at their documentation as it was clear they'd rather have you use their Meteor Cloud hosting solution over other providers. After finishing up my research and noticing the lack of deployment documentation in most of the frameworks, my opinion changed a bit on this matter and I give them kudos for providing information. 

Koa, in terms of their web presence, was the most interesting overall website as their site comprises of a single page containing the most minimal amount of documentation necessary to work with their framework. 

A general observation on the various documentation sites is that I almost feel like every site should use a search that delivers results in they way Algolia doc search does. It feels like I can find, or not find, what I am looking for quickly and efficiently. Whereas, the other sites not utilizing this search experience often feel slow to discovery.

### Quick starts and sample apps

Many of these frameworks I've never used before so this was also a cool opportunity to get acquainted with them. I made an effort to go through quick start tutorials, when available, or utilize sample apps that gave some description as to what makes their approach unique. 

The majority of the frameworks had a quick start or sample apps that were readily available but one definitely outshined the rest. LoopBack does a fantastic job at putting you right into their CLI and walking you through tutorials, getting you acquainted with their wizard API builders. 

LoopBack, with their wizard-builder approach, was also the most unique, in terms of interaction, amongst the different frameworks. 

### Ease of deployment

Now, let's get to the crux of the matter - which frameworks were the easiest to deploy with Cleavr and what were some of the common hurdles? 

Given that Cleavr has first-class support for Adonis apps, I won't spend time discussing Adonis as it's just a matter of a couple button clicks. 

It terms of ease-to-deploy, the older, more mature frameworks were overall the most intuitive and easiest to deploy to production. Hapi, Express, Koa, Sails and Total were all straightforward and required the least amount of effort. 

The most difficult to deploy was Meteor, mainly because it was the only one that required extra configs to be made at the server environment level, which was inconvenient. 

LoopBack and Foal both have CLI's that appear to be required to run their build processes. This required the CLI to be installed on the server before deploying. It's not a huge deal, and is just a one-time setup.

---

## General NodeJS deployment troubleshooting tips

These are some key things to watch out for when deploying your NodeJS apps to your VPS. If you deploy your app and see a 502 error, be sure to check these.  

### Hard-coded port numbers
Most of the samples, quick start apps, starters, etc tend to hard code the port number, often to 3000. For shared hosting, you'll likely want to make the port number more flexible and read from the environment setting. 

The majority of frameworks define the app's port number in the entry file - `app.js`, `index.js`, `server.js`, `main.js`, etc. 

What you can do is simply add `process.env.PORT` where the port is defined. 

Using Nest as an example, you'd update the `main.js` or `main.ts` file to look like:

```javascript
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT || 3000);
}
```

### App build output
If you need to build your app for production, you'll need to be aware of how the output is presented. Some build processes will output the artifacts in a new directory, which essentially will become your web directory. Such as, Nest will dump everything into a `dist` folder. 

### Start / entry point
Check the `package.json` file to see how the app will start. Some frameworks can be started using `npm run start` while others will have you define the entry point - which is often named something like `app.js`, `index.js`, `server.js`, or `main.js`.

Cleavr sets up PM2 for Node JS apps and creates a config file that will be referred to when starting the app via PM2. To know what to use, check the start script in your `package.json` file. 

For example, here is the start script for a basic Express app: 

```javascript
"scripts": {
    "start": "node ./app.js",
    ...
}
``` 
In this case, you'd use `app.js` as the entry point. 

### Framework specific CLI
As mentioned previously, some frameworks, such as LoopBack and Foal, will use the framework's proprietary CLI for build commands. If you are building on your target deployment server, then make sure it has been installed in order for the build process to run correctly. 

### Establish database connection
The last suggestion for 502 errors during production deployments is to make sure that if your app has a dependency on a database, to make sure the connection is established. 

When using PM2 for your NodeJS apps, run `pm2 log` to see what the app errors are. PM2's logs are typically pretty good at pinpointing why your app is failing in production. 

--- 

I hope this article is helpful and brings about a different perspective of common backend NodeJS frameworks. 

Another output of my effort to explore different Node frameworks to see how they can be deployed via Cleavr was to create several guides for each framework. Feel free to take a look - 

- [Adonis](https://docs.cleavr.io/guides/adonis)
- [Hapi](https://docs.cleavr.io/guides/hapi)
- [Express](https://docs.cleavr.io/guides/express)
- [Koa](https://docs.cleavr.io/guides/koa)
- [Sails](https://docs.cleavr.io/guides/sails/)
- [Total](https://docs.cleavr.io/guides/total)
- [Nest](https://docs.cleavr.io/guides/nest)
- [Loopback](https://docs.cleavr.io/guides/loopback)
- [Foal](https://docs.cleavr.io/guides/foal)