Configuring Nginx to Speed Up Your Ghost.io Blog

Adam Bard
Adam Bard
Share

Ghost is a hot new blogging platform. It’s simpler than WordPress, and exclusively focused on blogging (rather than being a full CMS, as WordPress has become). Like WordPress, you can sign up and host your blog on their site (for a price), or you can download and host Ghost yourself. We’ll focus on the latter.

Why Ghost?

I recently set up a blog for my wife (who writes about our travels) on my virtual server. Said VPS is shared with quite a few other apps, so I wanted to keep things efficient. The most efficient way to serve a blog is to use a static site generator like Middleman or Jekyll, and serve your static resources with a web server like Nginx. That’s fine for me — my personal blog uses Middleman and I updated it with Git post-receive hooks — but my wife’s not so into the command line, so I thought Ghost might be a better fit.

Said server is also serving a bunch of other little sites and apps, so I needed to keep it lightweight.

Ghost is a very well-made and good-looking piece of software written in Node.js — but that doesn’t mean it’s perfect. Node is great for many things, but when it comes to serving up static files, that task can be handled more efficiently with Nginx. Nginx is a fast, lightweight web server that is gaining more and more popularity, and one of the things it’s best at is serving as a proxy in front of other apps.

Today, I’ll show you how I configured my server so that:

  • Ghost serves up the admin pages (the only dynamic pages)
  • Nginx serves static assets (images, JavaScript, CSS)
  • All non-admin pages are cached by Nginx, further reducing load

All this will let my server’s resources go a lot farther. Plus, since Ghost ends up doing almost no work, I can leave it configured to use SQLite 3 instead of something more suited for parallel connections, which is a nice bonus.

Before We Continue

The process of installing Nginx and Ghost is beyond the scope of this article. For Nginx, you might try Nginx’s docs; for Ghost, you can follow Ghost’s installation instructions.

Configure Ghost to run on port 2368. We’ll proxy port 80 (i.e. the default http port) to it with Nginx. We’ll also assume you’re running on example.com.

Configuring Nginx to Serve Static Assets

To start with, you should have this bare-bones Nginx configuration:

server{
    listen 80;
    server_name example.com www.example.com;
}

First, we’ll make sure to serve the blog, which is running on port 2368. To do this, simply add the following:

location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:2368;
}

Now, make sure Ghost is running, and restart Nginx. When you navigate to your home page at example.com, you should see a blank Ghost blog.

We want to serve images and assets with Nginx. Ghost hides these around in a few different places, so you’ll need to make a few aliases. Add the following (changing the path to your Ghost install, and to your theme, appropriately):

location /content/images {
    alias /path/to/ghost/content/images;
}

location /assets {
    alias /path/to/ghost/content/themes/<mytheme>/assets;
}

location /public {
    alias /path/to/ghost/core/built/public;
}

location /ghost/scripts {
    alias /path/to/ghost/core/built/scripts;
}

Setting Up Static Site-style Caching

In order to use up as few cycles as possible, we want to be really aggressive with caching. So, for all the non-admin pages, we’re going to configure Nginx to ignore cache-control headers entirely and just cache each page for an hour.

Take out the other proxy_pass block. We’ll need to split it into two. The first will proxy requests to the admin backend, which we must not cache. The second will be the rest, which will be cached with a vengeance. Here’s what that looks like:

location /ghost {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:2368;
}

location / {
    proxy_cache STATIC;
    proxy_cache_valid 200 60m;
    proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:2368;
}

Ignoring the headers is optional, but we don’t mind clearing out the cache ourselves every now and then if it really needs it.

Speaking of which, you’ll also want to configure Nginx’s cache path. Above, we’ve called our configuration STATIC, so we need to add this line to our Nginx configuration’s http block (I put mine in /etc/nginx/nginx.conf):

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=STATIC:10m inactive=24h max_size=512m;

This tells Nginx to keep cache files at the path /data/nginx/cache, and sets the levels and various configurations. If you ever want to clear the cache, just execute rm -r /data/nginx/cache/* to remove all the cached files.

Everything All Together

Here’s the whole configuration, for reference:

server{
    listen 80;
    server_name example.com www.example.com;

    location /content/images {
        alias /path/to/ghost/content/images;
    }

    location /assets {
        alias /path/to/ghost/content/themes/<mytheme>/assets;
    }

    location /public {
        alias /path/to/ghost/core/built/public;
    }

    location /ghost/scripts {
        alias /path/to/ghost/core/built/scripts;
    }

    location /ghost {
        proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }

    location / {
        proxy_cache STATIC;
        proxy_cache_valid 200 60m;
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
        proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }

}

And that’s really all there is to it. With this setup, you should be able to serve many thousands of visitors from even a small private server.

Frequently Asked Questions on Configuring NGINX for Ghost Blog

What is the role of NGINX in hosting a Ghost blog?

NGINX is a powerful web server software that can also be used as a reverse proxy, load balancer, and HTTP cache. When hosting a Ghost blog, NGINX acts as a reverse proxy that directs web traffic from the internet to the Ghost software running on your server. This setup enhances the performance of your Ghost blog by efficiently managing the traffic and resources of your server.

How do I install NGINX on my server?

The installation process of NGINX varies depending on the operating system of your server. For most Linux distributions, you can install NGINX using the package manager of your system. For example, on Ubuntu, you can use the apt package manager to install NGINX with the command sudo apt install nginx.

How do I configure NGINX for my Ghost blog?

Configuring NGINX for your Ghost blog involves creating a server block in the NGINX configuration file. This server block specifies the location of your Ghost blog on your server and the URL that users will use to access your blog. You can create a server block by editing the NGINX configuration file, typically located at /etc/nginx/sites-available/default.

What is a server block in NGINX?

A server block in NGINX is a set of directives that define how NGINX should handle traffic for a specific domain or IP address. Each server block can contain directives for handling requests, managing SSL/TLS, and proxying requests to a backend server.

How do I secure my Ghost blog with SSL/TLS using NGINX?

To secure your Ghost blog with SSL/TLS, you need to obtain an SSL certificate from a Certificate Authority (CA) and configure NGINX to use this certificate. You can use the ssl_certificate and ssl_certificate_key directives in your NGINX server block to specify the location of your SSL certificate and private key.

How do I troubleshoot issues with my NGINX configuration?

If you encounter issues with your NGINX configuration, you can use the nginx -t command to test your configuration file for syntax errors. If the test is successful, you can reload the NGINX configuration with the sudo systemctl reload nginx command.

How do I optimize my NGINX configuration for performance?

Optimizing your NGINX configuration for performance involves tuning various parameters such as the worker processes, worker connections, and buffer sizes. You can also enable features like gzip compression and HTTP/2 to improve the performance of your Ghost blog.

How do I handle traffic spikes with NGINX?

NGINX can handle traffic spikes by adjusting the number of worker processes and connections, enabling load balancing, and using caching. These features allow NGINX to distribute traffic evenly across your server resources and serve cached content to reduce the load on your server.

How do I update my NGINX configuration?

To update your NGINX configuration, you need to edit the configuration file and reload the NGINX service. You can use a text editor like nano or vim to edit the configuration file, and the sudo systemctl reload nginx command to reload the service.

How do I uninstall NGINX from my server?

To uninstall NGINX from your server, you can use the package manager of your system. For example, on Ubuntu, you can use the apt package manager to remove NGINX with the command sudo apt remove nginx.