Nginx error pages and Ghost
1 min read

Nginx error pages and Ghost

If Ghost goes down everyone accessing the blog will run into an ugly 500 Internal Server Error page. Not only it looks bad, but it's also unclear for them: what happened? when will it be fixed? what can they do in the meantime?

I wanted a solution for this and the best one I came up with was to customize my server error pages. Not only it helps my blog, but also everything else on my VPS.

In terms of configuration, DigitalOcean has you covered with a great tutorial on using custom error pages with Nginx.

For a TL;DR version, just make your own pages (404.html and 50x.html) and upload them to /usr/share/nginx/html.

The second part would be to add them inside the site's conf file, which can be found in /etc/nginx/sites-enabled, where you will specify the new html files:

error_page 404 /custom_404.html;
location = /custom_404.html {
        root /usr/share/nginx/html;

error_page 500 502 503 504 /custom_50x.html;
location = /custom_50x.html {
        root /usr/share/nginx/html;

It's a good idea to test the syntax afterwards, with sudo nginx -t, to check for any typos, and then you can restart the server: sudo service nginx restart.

For example, here's my new 404 page. Not much, but nicer than before.

Now, in terms of the 500 error page, things were a bit different. I wanted something a bit more useful and the best thing I could do was to redirect the user to a cached version, in case it was available.

Nowadays, Google most likely has you covered and you can actually dynamically generate an URL to access Google's Webcache.

I made a redirect link for the user to click on:

<p>In the meantime, you can check for a <a id="cache-link" href="#" target="_blank">cached version</a> or try again in a few minutes.</p> 

and then I added the URL based on the current location:

var currentLocation = window.location.href,
    googleCacheURL = '' + currentLocation;

var cacheLink = document.getElementById('cache-link');
cacheLink.setAttribute('href', googleCacheURL);

You can see the end result here, on a fake broken location.

Simple, yet effective!