New Website. Moving From Grav to Hexo

About four years ago, I settled on Ubuntu 14 LTS[1] as the server operating system (OS) to host my website. We know that all good things must come to an end, and in the world of Ubuntu, we know precisely when that happens. As of April 2019, security updates for my server were no longer available. Since I didn’t want my server to be turned into a malware distribution system, a decision about upgrading the operating system had to be made.

ServerPilot, the company I chose to manage the server warned against upgrading in place. Too easily the upgrade can fail, leaving a broken system in its wake. Their advice is to set up a second server from scratch and then turn the switch to serve the website from the new server. Great advice, except they changed their pricing structure. I was grandfathered in on a free plan. The recommended path would “upgrade” me to one of their paid plans. Guess what I tried and guess what happened?

You guessed right, the upgrade in place failed. A complete reinstall of the OS and the website was in order.

Starting from scratch presented an opportunity to reconsider the choices I made when the website first went online and apply lessons learned. The rest of this post walks you through what I kept and what I changed and why. I hope this can be useful to someone else starting out or considering a switch.

The Server and Operating System

Since the first day, my website has been hosted on a virtual server from Ramnode. Over the years, they did everything I expected: Providing excellent and fast support when I needed help, and taking care of important security patches. I'm a happy customer. No need to make any changes here.

I have similar thoughts about the operating system. There aren’t many demands on the operating system to host a website; most flavors of Linux will work. So, no surprise here, my choice fell again on Ubuntu. Ubuntu offers a nicely configured minimal server version. It also ranks amongst one of the most widely used distributions, guaranteeing access to plenty of information about installing and maintenance. Currently, Ubuntu 18.04 LTS is the latest version, for which updates and security patches are provided until 2023.

Goodbye ServerPilot

When I started hosting my website, ServerPilot was a welcome service that took over server management. They configured a firewall, a webserver, and installed security and maintenance patches to keep the OS and webserver current. I had to keep an eye on the disk space and delete older and unused packages myself, but otherwise, the service was flawless.

That being said, over the years, I have grown pretty comfortable managing a server myself. Setting up the firewall is a one-time effort — and for a server dedicated to only serving websites a trivial one — and Ubuntu can install updates automatically. I received the SSL/TLS certificate for the website from Let's Encrypt; a cron job automatically renews them when they are close to expiring. That leaves securing the webserver software as the remaining task that I used ServerPilot for. But for a small website like the one that I’m hosting, where all the content is static, and no database is used, this isn’t a big job. Getting the initial installation secured and then making sure the software is kept up to date will do the job.

Goodbye Grav, Hello Hexo

Grav has served me well for a while. Until it didn’t. Relatively early on in my use of Grav I experienced errors after updating to a newer version. Accessing the website would simply throw a stack trace in the browser; an inscrutable log of the various function call layers the template engine was going through until it hit an error. At the time, I reverted to the previous version. When trying to install Grav onto the new server from scratch, I hit a similar problem. Putting the content in place as before, Grav handed me an error in the form of the stack trace. A good time to consider another way to serve the website content.

I was guided by staticgen, a site that lists static website generators. Based on my experience with Grav, I didn't consider anything that adds the complexity — often presented as convenience — of a content management piece. I focused on those generators that provide support for blogs out of the box to get access to blog-specific features like pagination and tag clouds. The one that piqued my interest was Hexo. It has an easy to navigate home page, is actively maintained, and has nice looking templates. The documentation outlines the process of writing and publishing a blog post in easy to follow steps. Overall, Hexo made a good impression on me. I found my replacement for Grav.

Configuring Hexo

Hexo is configured through YAML files. One is a site-specific configuration file the second file is specific for the selected theme. There are plenty of themes to pick from. I settled on «NexT». It is blog-aware, very configurable and responsive; a clear upgrade to the look and feel of my old site. Since the URLs created by Hexo didn’t match the old site I also installed a link alias generator. Everyone hates dead links, and this plugin allowed me to make sure the old links are simply redirected to the corresponding new URLs instead of presenting an “404 Page not found” error. I also needed a different markdown renderer that offers, amongst other things, footnote support[2].

SFTP deployer is the tool I settled on to move the web site onto the server. Previously, I deployed via git through bitbucket‘s webhooks, but I wanted to minimize the number of tools involved that require maintenance to keep things running (see here for a post supporting my point).

Picking and Securing the Webserver

In my previous webserver setup, ServerPilot automatically installed the webserver for me. Designed to support more sophisticated requirements than what I needed, that turned out to be a rather elaborate combination of NGINX and Apache. That would be overkill for my website. I looked at the differences between the two choices and picked NGINX. For a small static website, it is the better choice [3].

There are many easy to follow installation guides for NGINX. This guide from Digital Ocean is specific to the exact version of Ubuntu that I needed. I pretty much just followed the guide. But, installation is one thing, hardening and securing the site is another. There are steps to take that apply to NGINX in isolation, but those don’t cover issues introduced by the website itself. So I turned to Nikto, an open-source webserver scanner. Pointing it at my website, it provided the following information:

- Nikto v2.1.6
+ Target IP:
+ Target Hostname:
+ Target Port: 80
+ Start Time: 2019-09-15 13:03:58 (GMT0)
+ Server: nginx
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ OSVDB-3092: /sitemap.xml: This gives a nice listing of the site content.
+ OSVDB-3092: /archives/: This might be interesting...
+ OSVDB-6694: /.DS_Store: Apache on Mac OSX will serve the .DS_Store file, which contains sensitive information. Configure Apache to ignore this file or upgrade to a newer version.
+ /: A Wordpress installation was found.
+ 7917 requests: 0 error(s) and 4 item(s) reported on remote host
+ End Time: 2019-09-15 13:53:47 (GMT0) (2989 seconds)
+ 1 host(s) tested

Some of the items it listed are also covered by the hardening guide I already pointed to earlier. The one that brought a bit of an “oops” moment was OSVDB-6694. I was browsing the site directory Hexo had created on my Mac in the Finder right before I uploaded the directory structure to the webserver. Browsing with the Finder on my Mac was what created the .DS_Store files. Lesson learned: Updating my website has to be an atomic operation of

hexo clean 
hexo generate
hexo deploy

to make sure only files created by Hexo are actually uploaded to the server.

The new website is now up and running. The process was relatively quick and painless, and I should be good until 2023 when Ubuntu 18.04 stops being supported.

Picture Credits:

  1. LTS stands for Long Term Support.

  2. Footnotes are used abundantly on my website.

  3. Note that given the minuscule amount of traffic that my website gets compared to what either of those webservers can handle, the choice is most likely inconsequential.