Chris Mallinson Chris Mallinson at night
Chris Mallinson

Vapid on DigitalOcean

Posted on November 1, 2018

Vapid is a new light CMS that runs on Node.js and features a really cool template-driven system of defining editable content, and a simple dashboard for updating the site. They currently offer a private beta to host sites on their secure platform, or you can self-host. I've used Vapid for this site, and I'm going to show you how to do it.

Vapid Announcement Vapid Home Page Vapid Documentation

Creating a DigitalOcean Droplet

Sammy the Shark - The DigitalOcean MascotYou don't have to use DigitalOcean for your site, but I use them for everything and could not be happier with their servers. Adding servers is a breeze, and everything is fast. If you have not created an account at DigitalOcean, you’ll need to do that first. Sign up using my link and you’ll usually get $25 in credit, but right now they have a promotion where you can get $100 in credit to be used over the first 60 days.

I recommend creating a droplet using the Ubuntu 18.04 Node.js One-click image. Just use the smallest droplet for now. Even the 1GB/1CPU server will be plenty fast for most sites, and you can easily scale up later. Unless this is really just a test droplet, I also strongly recommend adding the backup option for a 20% fee. Always have backups, and backups of backups.

An Image of the DigitalOcean List of One-click Apps with the Node.js one selected

For the region choice, it’s a good idea to choose a region closest to where your visitors are, or one in a country with privacy laws that are aligned with your values. If you’ve not added your SSH key to your DigitalOcean profile, this is a good time to do that. It will make logging into your droplet much easier and more secure.

If you're not familiar with using public SSH keys as a way to manage your logins, now is a good time to read up on it. DigitalOcean provides really good tutorials on everything you need to set up your servers.

Uploading SSH Public Keys to a DigitalOcean Account

Creating the droplet takes around a minute. Use that minute to think about what it took for old school web people like me to obtain a hosting account in 1996.

Has your droplet been created? If so, type IP address (or hostname, if you've already pointed a domain to the machine) in the field below, and the rest of the instructions will be customized for you. If you're planning on using this for a site that already has a domain name, point a subdomain to this server. It's a lot easier to remember than a random IP address, and you'll be able to set up SSL as well.

Open up a terminal, and type login to your instance as the root user.

ssh root@#HOSTNAME#

The first thing to do is to add a regular user. It’s a bad idea to be logging in as root all the time. Type the username you wish to use in the box below. Then run the following commands. You'll be asked to create a password, and enter some optional information about the user.

adduser #USERNAME#

usermod -aG sudo #USERNAME#

If you set up your droplet using SSH keys for login, the following command will copy the SSH key being used for your root login to the new user. If not, you can skip this, and use the new user's password to login when you reconnect.

rsync --archive --chown=#USERNAME#:#USERNAME# ~/.ssh /home/#USERNAME#

This gives you a limited access account but still allows you to run admin tasks using sudo when you need to. Logout from your root acount and back in with your regular user.

exit

ssh #USERNAME#@#HOSTNAME#

We’re going to run some updates and install Nginx (the webserver we're going to use) and the latest Node.js updates.

sudo apt update

sudo apt install nginx

sudo ufw allow 'Nginx Full'

curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -

sudo apt install nodejs

This installs Nginx as a webserver, and updates Node.js to the latest versions. The next few steps involve setting up your web root and setting the folder permissions.

sudo mkdir -p /var/www/#HOSTNAME#/html

sudo chown -R $USER:$USER /var/www/#HOSTNAME#/html

sudo chmod -R 755 /var/www/#HOSTNAME#

Next, we need to register the site with Nginx. Create a config file for your site with the next command.

sudo nano /etc/nginx/sites-available/#HOSTNAME#

This will create a file, and open an editor. Paste the following into the file:

server {
        listen 80;
        listen [::]:80;

        root /var/www/#HOSTNAME#/html;
        index index.html index.htm index.nginx-debian.html;

        server_name #HOSTNAME#;

    	location /{
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Use CTRL-X and type Y to save the file. Then run the following command.

sudo ln -s /etc/nginx/sites-available/#HOSTNAME# /etc/nginx/sites-enabled/

Now we need to edit the Nginx config file

sudo nano /etc/nginx/nginx.conf

Now within this file, scroll down until you see the server_names_hash_bucket_size directive, and remove the "#" at the start of the line, so that this:

24
25  # server_names_hash_bucket_size 64;
26  # server_name_in_redirect off;

Becomes this:

24
25  server_names_hash_bucket_size 64;
26  # server_name_in_redirect off;

Now restart Nginx to apply the settings.

sudo systemctl restart nginx

Vapid!

We're ready to install Vapid now. These steps are the same steps you may have already followed if you installed Vapid locally. We're going to set up Vapid on your DigitalOcean droplet as a production environment, so you should do all your development work on your local machine. The production version minimizes your javascript, and employs come caching to speed up the site.

mkdir ~/apps && cd ~/apps

sudo npm install -g vapid-cli --unsafe-perm

vapid new ~/apps/#HOSTNAME#/ && cd ~/apps/#HOSTNAME#/

At this stage you can start up your website with the command vapid start . but that will only run the site until you close down your terminal window. We want the site to run all the time, and we want it to start up automatically if your server is restarted, or if the process crashes. We're going to use a tool called PM2 to accomplish this. First we'll create a config file in your app's root that will hold the settings required to start up your site. Use the following command to create the file, and then copy the subsequent JSON into the file. Then close (CTRL-X) and save.

sudo nano ~/apps/#HOSTNAME#/pm2.json

{
  "apps": [
    {
      "name": "#HOSTNAME#",
      "script": "npm",
      "args": "start",
      "env": {
        "NODE_ENV": "production",
        "PORT": "3000",
      }
    },
  ]
}

This tells PM2 to run the server on the standard port for vapid (3000) so that your site will be accessible locally at http://localhost:3000. Nginx will make that site accessible externally using your IP address or domain.

With that configuarion file in place, we install PM2.

sudo npm install pm2@latest -g

With PM2 installed, let's supply it with our application specific JSON file to start up our Vapid site.

cd ~/apps/#HOSTNAME#

pm2 start pm2.json

pm2 startup systemd

That last command will give you an output that includes another command to run. It will look something like this:

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u #USERNAME# --hp /home/#USERNAME#

Your site should work at this point, having been started as a background process by PM2. Check it out here. Now run the following command to save your PM2 configuration.

pm2 save

Securing the site with Let's Encrypt

This will only work if you've used a domain name for your site, and have pointed it to this server. Let's Encrypt will only issue certificates for domain names - or subdomain names, not bare IP adresses.

Let's Encrypt is a free service that has simplified the process of setting up SSL certificates, and allows even test sites to easily be set up with the https protocal. It's a quick way to automate the entire process, and even automate the future renewal process. The following commands will install certificates to your new site, and will ask you for some information to create your certificate. It will also ask you about redirection of http requests to https. I usually say yes to this.

sudo add-apt-repository ppa:certbot/certbot

sudo apt-get update

sudo apt-get install -y python-certbot-nginx

sudo certbot --nginx

All done. Your site should now redirect to https://#HOSTNAME#.

Next Steps

You've now got the demo version of Vapid running on your server. If you've worked on a vapid site locally, you can upload your templates and assets to the application root to move your site to this server. I recommend you use Git to manage your site's files, checking in changes from your development environment, and pulling the changes to your server, but that's another tutorial.

It would also be a good idea for high volume sites to add a more robust database for your app. Vapid can support MySQL, PostgreSQL, and several others. Again, that's a future tutorial.

Got a comment, or a suggestion to make this guide better? Send me an email. I've run through this guide twice now on fresh DigitalOcean droplets, so I'm pretty sure it works, but since I'm fairly new to Node.js, I'm sure some seasoned pros could improve on this.