Create a Hapi.js Web Application Using Node.js on Ubuntu 16.04

Published on: Fri, Jun 15, 2018 at 11:15 am EST

Hapi.js is a rich, robust, and powerful Node.js framework designed for building web applications in the Node.js ecosystem. Its straightforward design makes it easy to get started with. Hapi uses many of the latest JavaScript ES6 features at its core, such as ES6 promises. For those of you who have used Express before, Hapi allows you to try something new, and experience all of the latest JavaScript features.

In this tutorial, our goal will be to set up a basic Hapi.js web page, which is hosted from our Vultr VPS, on Ubuntu 16.04 LTS. For those who have a domain for their site, we will be using a reverse proxy to link our domain to our website. Finally, we will be learning how to manage it with a process manager. Now that we've got that out of the way, let's get started.

Installing Node.js

We will need to install Node.js. To do so on Ubuntu 16.04 LTS, follow these instructions.

Adding the Repository

We will need to add the NodeSource APT repository, which contains the latest LTS release of Node.js.

curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

We are downloading a script that we will use to add the repository to our sources list, as well as installing Node.js from the NodeSource repository.

Installing Build Tools

In addition to installing Node.js itself, we will also need to install some necessary build tools, which will assist in building any modules that we may need to install.

sudo apt-get install -y build-essential

This simply downloads and installs the build tools from the repository.

Setting up application directory

It is good practice to designate a folder that we will use for our application, which will contain all of our application's data, such as configuration files and startup scripts. Create a folder, naming it whatever you'd like. For the sake of this tutorial, I'll assume you named it site.

mkdir site

Once you have made the folder, now we can change into it. Making sure you are in the directory that you have just created, start up the NPM package wizard.

npm init

It will ask you to input a few different things, such as your application name, start file, license and so on. Most fields you can leave default, except for the more obvious fields, such as the name of your application. In the end, it will look like this:

{
  "name": "site",
  "version": "1.0.0",
  "description": "Hapi.js site",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "rich",
  "license": "MIT"
}

Once you are satisfied with the result, click ENTER to save the file.

Installing Hapi.js

Now that your directory has been successfully constructed, we can now proceed to install Hapi.js. As mentioned before, we will be utilizing NPM to download Hapi.js, as well as its dependencies, for our project. In the project directory, run the following.

npm install hapi.js

This downloads Hapi.js from NPM and installs it in our project directory. In the same run, any dependencies that Hapi.js may rely on are also downloaded for our convenience.

Setting up our sample application

Now it is time to set up our base Hapi.js application file. This will contain all of our code for the application. Further down the road, we can expand on our application code, and add more things to it, as we see fit.

Next, we will create our start file. Refer back to the main section of your package.json file, to determine exactly how to name the file. Since I used the default naming scheme, our file will be called index.js.

nano index.js

Once you are inside the nano text editor, create your base application code, like so.

const Hapi=require('hapi');
const server=Hapi.server({
    host:'localhost',
    port: 3000
});

server.route({
    method:'GET',
    path:'/',
    handler:((request,h)) => {
        return 'Sample Hapi.js Application';
    }
});
async function start() {

    try {
        await server.start();
    } catch (err) {
        console.log(err);
        process.exit(1);
    }
    console.log(`Our server is running! ${server.info.uri}`);
};

start();

First, we import the Hapi module. Then, we initialize our server constructor, which contains the host we want to run the server on, as well as the port, which is 3000 for this tutorial. Next, we set up a basic router, which indicates that whenever someone visits the site, they'll be greeted with a simple message. To top it all off, we have an async function, to start our server, which will log to the console that our server is running. When you're finished, save and close the file (CTRL + X)

Now that our main file is set up, we are ready to start our application.

node index.js

If you see "Our server is running!" in the console, then the server started up successfully.

Install Nginx

Since Nginx is available in the default Ubuntu repositories, installation is straightforward. Simply update your package lists, and install it.

sudo apt update
sudo apt install nginx -y 

After refreshing the package lists, Nginx and its dependencies will be installed.

Configure Nginx

In order for Nginx to reverse proxy our application, we'll need to create a configuration file. This configuration file will hold information about our application, which Nginx will use for the reverse proxy.

Delete the default configuration that Nginx created, as we'll be replacing it with our own later.

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

Make a new file in the sites-available folder. As for naming, we can stick to simply site, for simplicity.

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

In the file, paste the following, and save.

server {
    listen 80;
    location / {
          proxy_set_header X-Real-IP 
          $remote_addr;
          proxy_set_header 
          X-Forwarded-For 
          $proxy_add_x_forwarded_for;
          proxy_set_header Host 
          $http_host;
          proxy_set_header 
        X-NginX-Proxy true; proxy_pass 
       http://127.0.0.1:3000/;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade 
     $http_upgrade;
    proxy_set_header Connection 
    "upgrade";
    proxy_redirect off;
    proxy_set_header 
   X-Forwarded-Proto $scheme;
    }
}

In this file, we are telling Nginx to listen on port 80. We are also setting the proxy passthrough to the localhost address, and port 3000, which is the same port as our Hapi application.

Now you can navigate back to your application directory, and start the site. Once the site has started, simply navigate to http://yourdomain.com or http://yourip, and you will see the text "Hello World".

Install PM2

PM2 can be found in the NPM repository, and you can install it globally to be accessible from anywhere, like so.

sudo npm install pm2 -g

The -g flag at the end indicates that we want to install the module to the global modules folder, which will allow us to use it outside of our project directory. This is used in order for our project to behave like a normal system application.

Starting our app with PM2

Once you've installed PM2, navigate back to your project directory. The syntax to start our application will be slightly different now. This is how we will do it with PM2.

pm2 start index.js --name site

We utilize the PM2 start function, which basically creates a profile for our application, under the name site. After running that command, your website will start, but you'll notice that the logs will not show. That's because the way we view logs now is different.

pm2 logs site

You can even specify how many lines of logs you want to see, with the --lines argument.

Conclusion

You have successfully set up a Hapi.js web server, reverse proxied it with Nginx, and learned how to better manage it with PM2. With this knowledge, you can further expand on this tutorial and make a very advanced Hapi.js application. To learn more about the possibilities of Hapi, visit their official documentation. If you'd like to learn more about the possibilities of PM2, refer to their quick start guide.