Skip to main content

sometechblog.com

Deploying Gatsby on a VPS

Table of Contents

Although it is clearly not in fashion at the moment, deploying websites on a VPS (virtual private server) or regular server for that matter, without any containerization and orchestration is both fast and easy. I have been running my private VPS (with Ubuntu 16.06) for years without much sweat. Using the command line to install and configure a server is both easy and powerful once you know the basic. No need to bother with a fancy UI layer or the limitions it often imposes.

Initially, you configure ssh login keys and add automatic security updates (unattended-upgrades with which I never have had any reliability issues. Speaking of reliability, I even run sudo apt-get update && sudo apt-get upgrade occasionally, likewise without problems). Then install Nginx, Node, MySQL, Git and Certbot. This setup have not only served my private hosting requirements without any problems nor high bills, but also multiple of my own failed startup projects.

Gatsby is properly the most popular static site generator. It has an extensive ecosystem of plugins, good documentation and is easy to use. These are the key advantages. Don’t let the sales talk fool you, it is rather underwhelming to sit and wait 12 seconds while Gatsby builds. And speaking of “blazing fast”, for a simple blog it would without a doubt be “blazing faster” to simply use an almost static HTML page without all these useless JS and JSON that is being bundled with the site.

## Installing Gatsby

Install gatsby-blog-starter theme:

npx gatsby new my-blog https://github.com/gatsbyjs/gatsby-starter-blog

Now besides configuring it (e.g. filling in blog name, picture, description, removing dummy content etc.), you can deploy it. Here is a link to the theme.

## Deploying to VPS

Assuming you already have a VPS and ssh access to it, you can deploy my-blog folder to it. Add deploy.sh script to the root of my-blog and make executable: chmod +x deploy.sh:

#!/bin/bash

echo 'Building assets...'

yarn build

echo 'Synchronizing assets with server...'

rsync -az --force --delete --progress public/ username@your-server-ip:/home/username/www/probject-name

You can now call it directly from the terminal: ./deploy.sh or add it to your package.json:

"scripts": {
  "deploy": "./deploy.sh"
}

The local build folder (/public) is being sync with home/username/www/probject-name on your server. You now need a web server and Certbot for adding SSL certificates:

ssh username@your-server-ip

sudo apt-get install nginx

// certbot PPA
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

sudo apt-get install certbot

To add your mydomain.com to Nginx, add: > /etc/nginx/sites-available/mydomain.com with the following content:

server {
  listen 80;
  server_name mydomain.com www.mydomain.com;
  return 301 https://mydomain.com$request_uri; // redirect http to https
}

server {
  listen 443;
  server www.mydomain.com;
  return 301 https://mydomain.com$request_uri; // redirect www to non-www
}

server {
  listen 443;
  server_name mydomain.com;
  root /home/username/www/mydomain.com;
  access_log off;
  error_log off;
  add_header Cache-Control no-cache;

  location ~* \.(ico|jpg|jpeg|png|gif|ico|css|js|txt|svg|ttf|eot|woff|woff2)$ {
    // All files except .html, .json and xml should be cached
    add_header Cache-Control "public, max-age=31536000, immutable";
  }

  location / {
    try_files $uri $uri/ =404;
  }
}

Adding SSL with Certbot:

sudo certbot --nginx -d mydomain.com -d www.mydomain.com

Choose “no redirect” when asked, because it is already in the website config. Certbot will automatically add SSL certificate to your website config. Make a symlink of the website config to enable it:

ln -s /etc/nginx/sites-available/mydomain.com /etc/nginx/sites-enabled/mydomain.com

// Reload Nginx
sudo service nginx reload

Your blog should now be running on your domain.

If you want to automatically deploy on push you to master, you just need to add your deploy script to a git hook.