Setup a Keystone.js Server Using Nginx Reverse Proxy on Ubuntu 16.04

Last Updated: Mon, Jan 15, 2018
CMS Linux Guides Server Apps Ubuntu Web Servers
Archived content

This article is outdated and may not work correctly for current operating systems or software.

In this tutorial, we will be setting up a web server with a reverse proxy. The CMS we will be using is Keystone.js, a well known web application framework based off of Express.js. The reverse proxy we will be using is Nginx, which is a free and open-source reverse proxy, as well as an HTTP server. The database we will be using is MongoDB, a NoSQL document database. This will require that you have a domain with records set up. If you don't have that set, then go ahead and get that taken care of, and come back to this tutorial.

Installing Node

First, we will install Node.js, which is a Javascript interpreter based on the Chrome V8 Javascript engine.

curl -sL | sudo -E bash -

sudo apt-get install -y nodejs

sudo apt-get install -y build-essential

Installing Nginx

Next, we will install Nginx, our reverse proxy.

sudo apt update

sudo apt install nginx

This will update the package lists, and install Nginx. Once the installation is done, we will setup our node project.

Initializing our Keystone project

Create our node project. To do that, simply create a new folder.

mkdir website

Then, we will create our package.json file. To do that, simply run npm init in your terminal, fill out the fields, and reply "yes" to confirm. Once you have created the package.json file, then we will install the following node modules.

sudo npm install -g generator-keystone

sudo npm install -g yo

Once those are finished downloading, run the following.

yo keystone

Fill out the required fields. It will ask you for the project name, the template engine, email for control panel, and so on. If you do not know what to select, then the defaults will be fine.

After you have configured your keystone setup, we can test to see if our server is running by typing node keystone to start your application. By default, your application will be running on localhost, on port 3000. Note that if you do not have MongoDB installed, a database will not be available for you right away. You can learn how to install it later in the tutorial.

Here is the basic directory layout for Keystone.js:

  • /lib - This is where you will store your custom libraries, and other code.

  • /models - This is where you will store your application's database models. KeystoneJS uses MongoDB as a database provider.

  • /public - This is where your static files (CSS, JS, images, and so on) will be stored.

  • /routes/api - This is where your application's API controllers will be stored.

  • /routes.views - Application view controllers will be stored here.

  • /templates - This is where all of your application's template files will be stored.

  • /updates - This is where your migration scripts will be stored.

  • package.json - This is your npm configuration file that the generator generated for us.

  • keystone.js - Our main start file, we run this when we start up the website.

Initializing our database

As mentioned earlier, our database that we will be using is MongoDB, which is a reliable NoSQL, document-oriented database. If you already happen to have MongoDB installed, you may skip this section. If not, then here's how to install it on Ubuntu 16.04.

Import the public key used for the mongoDB package.

sudo apt-key adv --keyserver hkp:// --recv 0C49F3730359A14518585931BC711F9BA15703C6

Create the list file used to install the package.

echo "deb [ arch=amd64,arm64 ] xenial/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list

Update your package lists using apt.

sudo apt update

Finally, install MongoDB.

sudo apt install mongodb-org -y

When this installation has finished, start MongoDB.

sudo service mongod start

This will start the MongoDB process on port 27017.

MongoDB will be used throughout the application, and it will be utilized to store information that we use for our models, for example a User model. Keystone uses it as it's database of choice, and at this time you cannot use other database vendors.

Installing PM2

Now it is time to install PM2 (Process Manager 2.) PM2 is a process manager for Node.js applications, in the form of an npm module. It provides an easy way for you to manage your applications and run them in the background. Because it is in NPM, all we have to do to install it is run the following.

sudo npm install pm2 -g

This tells npm to install it globally, so we can use it anywhere in our system.

Running/Managing an application on PM2

Earlier, we ran our web application with node keystone. With PM2, it's a bit different. We now run our node app with the following.

pm2 start keystone.js

This will add our PM2 application to our process list, and a little box will be displayed so you can see that it is indeed online. Notice the box labeled id for your process. Keep this close, as we will be making many references to this later on.

To see the logs for your application.

pm2 logs [id]

For example, pm2 logs 0 if this is your first PM2 application.

To stop your web application at any time.

pm2 stop [id]

To completely delete your application.

pm2 delete [id]

PM2 even has a monitoring dashboard if you want to see some basic stats for your application, and you can access it with this.

pm2 monit

This will show some basic information such as RAM usage, CPU usage, and uptime.

A great feature that PM2 offers is watching. In essence, watching is when PM2 auto-detects changes to any of the files in the same directory as your start file, and it will automatically restart your application. To enable it, simply restart your application, but pass it a watch flag.

pm2 restart [id] --watch

To disable watching after it has been enabled, simply run the same command again, and watching will be disabled.

In this tutorial, we will leave watching off.

Setting up your reverse proxy

Make sure you have Nginx installed. If for some reason it is not, reference the steps above.

Adjust your firewall settings. On Ubuntu, ufw is the official firewall. By default, connections are blocked on port 80. We need to add an exception for Nginx on port 80, which our web application will be running on.

sudo ufw allow 'Nginx HTTP'

Verify that your Nginx server is running.

systemctl status nginx

Under the Active section, if you see active (running), then you are all set. If not, you can try restarting the service.

systemctl restart nginx

Delete the default Nginx configuration file.

sudo rm /etc/nginx/sites-available/default

Create a new one, and simply call it node.

sudo nano /etc/nginx/sites-available/node

Paste the following into the file, and replace with your website domain.

listen 80;


    location / {

        proxy_set_header   X-Forwarded-For $remote_addr;

        proxy_set_header   Host $http_host;

        proxy_pass         "";



Note that the proxy_pass denotes the IP our Keystone app is running on locally, which is localhost on port 3000.

listen 80 is the port we want the app to be directed to, which in this case is port 80.

Then, we need to create a symlink, or symbolic link to a folder called sites-enabled. The difference between sites-enabled and sites-available is that sites-enabled is actually loaded by Nginx.

sudo ln -s /etc/nginx/sites-available/node /etc/nginx/sites-enabled/node

Now your configuration file in sites-available will be ready to use, and it will be loaded from sites-enabled.

To apply the configuration so it takes effect, simply restart Nginx.

sudo systemctl restart nginx

Finally, restart your PM2 application

pm2 restart [id]

Now you can navigate to your domain in a browser, and you will see a Welcome to Keystone screen, with a panel for you to log in.

If you see it, then you have successfully set up a Node.js production web server. If not, then you may have done a step incorrectly, and you may want to go back and follow each step carefully.

You can learn more about Nginx by visiting their website.

I hope you enjoyed this tutorial, and I hope this has helped you set up your own web server for production on your Vultr VPS.

Want to contribute?

You could earn up to $600 by adding new articles.