Reader small image

You're reading from  Building Enterprise JavaScript Applications

Product typeBook
Published inSep 2018
Reading LevelIntermediate
PublisherPackt
ISBN-139781788477321
Edition1st Edition
Languages
Right arrow
Author (1)
Daniel Li
Daniel Li
author image
Daniel Li

Daniel Li is a full-stack JavaScript developer at Nexmo. Previously, he was also the Managing Director of Brew, a digital agency in Hong Kong that specializes in MeteorJS. A proponent of knowledge-sharing and open source, Daniel has written over 100 blog posts and in-depth tutorials, helping hundreds of thousands of readers navigate the world of JavaScript and the web.
Read more about Daniel Li

Right arrow

Chapter 10. Deploying Our Application on a VPS

In the last few chapters, we created a robust user directory API, which is now ready to face the outside world. Thus, in this chapter, we'll learn how to expose our API to the World Wide Web (WWW). First, we will need to set up a Virtual Private Server (VPS) to host and serve our API, and associate it with a public, static IP address; we will achieve both of these goals using DigitalOcean (DO), a popular cloud provider. Then, to make it easier for our API consumers, we'll purchase a domain name from a domain registry, and configure its Domain Name System (DNS) records to resolve the domain name to the static IP.

By following this chapter, you will:

  • Learn to set up and secure a VPS
  • Learn about privileged ports
  • Keep processes alive using PM2
  • Set up NGINX as a reverse proxy to our API
  • Understand the architecture of the DNS
  • Purchase and configure a domain name

Obtaining an IP address


The internet is a giant network of interconnected machines. For these machines to communicate with one another, each machine must have a unique identifier. The internet uses the TCP/IP protocol for its communication, which in turn uses the IP address as its unique identifier. So, the first requirement for exposing our API to the internet is to have an IP address.

 

If you are paying for internet at home, you too will have an IP address provided to you by your Internet Service Provider (ISP). You can check your IP address by using an external service such as ipinfo.io:

$ curl ipinfo.io/ip
146.179.207.221

This means it's theoretically possible to host your API using your home PC, or even your laptop. However, doing so is problematic because of the following reasons:

  • Most consumer-grade internet plans provide dynamic IP addresses, rather than static ones, which means your IP can change every few days
  • Many ISPs block incoming traffic to port 80, which is the default HTTP port...

Setting up a Virtual Private Server (VPS)


There are many VPS providers, such as the following:

For this book, we are going to use DigitalOcean (DOdigitalocean.com). We picked DO because it has a very intuitive user interface (UI), where everything (VPS, DNS, block storage, monitoring, Kubernetes) can all be managed on the same dashboard. This is unlike AWS, which has an outdated and cumbersome UI.

Now, go to the DO website (digitalocean.com) and create an account.

Note

You should use this referral link: m.do.co/c/5cc901594b32; it will give you $10 in free credits!

DO will ask you for your billing details, but you won't be charged until you've used their services. You should also...

Running our API


Before we can run our API on the VPS, we need to install the software and libraries it depends on, which include Git, Node, yarn, the Java Development Kit (JDK), and Elasticsearch:

hobnob@hobnob:$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
hobnob@hobnob:$ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
hobnob@hobnob:$ sudo apt update && sudo apt install yarn git default-jdk
hobnob@hobnob:$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
hobnob@hobnob:$ echo 'JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"' | sudo tee --append /etc/environment > /dev/null
hobnob@hobnob:$ cd && wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.2.deb
hobnob@hobnob:$ sudo dpkg -i elasticsearch-6.3.2.deb
hobnob@hobnob:$ rm elasticsearch-6.3.2.deb
hobnob@hobnob:$ sudo systemctl start elasticsearch.service
hobnob@hobnob:$ sudo systemctl enable...

Keeping our API alive with PM2


We are running our Node.js process inside an ephemeral SSH session. When we log out, the host machine will kill any processes initiated during that session. Therefore, we need to come up with a way of keeping our process alive even after logging out.

Furthermore, no matter how good our code base is, or how complete our test plans are, in any application of significant size, there will be errors. Sometimes, these errors are fatal and crash the application. In these instances, we should log the error and notify the developers, but most importantly, we should restart the application as soon as it crashes.

Ubuntu provides the upstart daemon (upstart.ubuntu.com), which can monitor a service and respawn it if it dies unexpectedly. Likewise, there's a popular npm package called forever (github.com/foreverjs/forever), which does a similar job. However, I have found PM2 (pm2.keymetrics.io) to be the best process manager out there, so that's what we'll use in this book...

Running our API on port 80


We are currently running our API server on port 8080, whereas the standard port for HTTP requests is port 80. It would be really inconvenient, and thus bad for user experience, to ask the consumers of our API to attach a port number to the URL for every request.

Therefore, let's change the port that Express is listening on from 8080 to 80 and see what happens. Change the SERVER_PORT environment variable to 80:

SERVER_PORT=80

Then, stop and delete the PM2 application, and run the serve script again. When we run it again, it will initially be successful:

hobnob@hobnob:$ npx pm2 delete 0; yarn run serve
...
[PM2] Done.
┌───────┬──────┬────────┬───┬─────┬─────────┐
│ Name  │ mode │ status │ ↺ │ cpu │ memory  │
├───────┼──────┼────────┼───┼─────┼─────────┤
│ index │ fork │ online │ 0 │ 0%  │ 16.9 MB │
└───────┴──────┴────────┴───┴─────┴─────────┘

However, when we check its status again, PM2 will show you that the application has errored, and it has tried to restart it 15...

Setting up NGINX


So let's get NGINX installed on our machine!

Note

We will outline the installation instructions for NGINX on Ubuntu. Installation for other platforms can be found at nginx.com/resources/wiki/start/topics/tutorials/install/

 By default, the nginx package should already be in Ubuntu's default repositories:

hobnob@hobnob:$ apt-cache show nginx
Package: nginx
Architecture: all
Version: 1.14.0-0ubuntu1
...

However, we should use the official NGINX repository to ensure we always get the most up-to-date version. To do this, we need to add NGINX's package repository to the list of repositories that Ubuntu will search for when it tries to download packages.

By default, there are two places that Ubuntu will search: inside the /etc/apt/sources.list file and inside files under the /etc/apt/sources.list.d/ directory. We should not write directly to the /etc/apt/sources.list file because when we upgrade our distribution, this file will be overwritten. Instead, we should create a new file...

From IP to domain


Right now, we can access our API using an IP address. But if we want developers to use our API, we shouldn't expect them to remember a random sequence of numbers! Instead, we want to give them an easy-to-remember domain name such as api.hobnob.social.

To do that, we must first purchase the domain name and then configure its Domain Name System (DNS) settings so that it will resolve to our server's IP address.

Buying a domain

While the DNS is responsible for resolving domain names to IP addresses, a domain registrar is the entity/business that registers the domain(s) for you. There are many registrars available; the one we will be using is Namecheap.

First, we must search for the domain we want on the Namecheap website. Although a registrar is an entity that can register domain names for many TLDs, it must first check with one or more domain registries to see whether the domain name is available. Domain registries collectively hold a list of all domain names and their availability...

Summary


In this chapter, we have deployed our code to a VPS and exposed it to the external world—first through a static IP address, and later via a domain name.

In the next chapter, we are going to look into Continuous Integration (CI) and Continuous Deployment (CD) to see how we can automate the testing and deployment steps we've introduced in the last few chapters. You'll get the chance to work with Travis CI and Jenkins, a build automation tool.

Looking further ahead, in Chapter 17, Migrating to Docker and Chapter 18, Robust Infrastructure with Kubernetes, we will use Docker containers and Kubernetes to make our deployment more scalable and reliable.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Building Enterprise JavaScript Applications
Published in: Sep 2018Publisher: PacktISBN-13: 9781788477321
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Daniel Li

Daniel Li is a full-stack JavaScript developer at Nexmo. Previously, he was also the Managing Director of Brew, a digital agency in Hong Kong that specializes in MeteorJS. A proponent of knowledge-sharing and open source, Daniel has written over 100 blog posts and in-depth tutorials, helping hundreds of thousands of readers navigate the world of JavaScript and the web.
Read more about Daniel Li