Using Nginx to create a separate landing page for your Ghost Blog

Ghost's Blogging platform is great but its fairly new, and the lack of customization options available can be a little frustrating sometimes. For example, there is currently no way from within Ghost to create a static home page, and a list of posts available at /blog. This is because Ghost themes can only access the full array of posts on the root of the site at /.

This problem is usually solved by having the entire Ghost installation sit behind /blog/*. This was not an ideal solution in our case, because our site started out as a blog only. Changing the path to our blog now would break all of the post links we have shared so far.

We were able to achieve our desired affect using the Nginx configuration below. (Nginx is a free, open-source platform most popularly used as a high-performance HTTP server and reverse proxy). This article assumes you have a basic working knowledge of getting Nginx up and running, or are using the 1-Click Ghost installation provided by Digital Ocean.

Below is the nginx configuration found at /etc/nginx/sites-available/ghost on the Digital Ocean Ghost Image.

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    # Replace with your domain
    server_name codehangar.io;

    root /usr/share/nginx/html;
    index index.html index.htm;

    client_max_body_size 10G;

    # Does an exact match on '/' and loads custom landing page
    location =/ {
        root /var/www/ghost/content/themes/code-hangar-ghost-theme;
        try_files /landing-page.html /landing-page.html; 
    } 

    # Does an exact match on '/blog/' and routes it to
    # ghost's normal homepage with posts loop
    location =/blog/ {
        proxy_pass http://localhost:2368/;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
    } 

    # Existing Ghost location.
    # Every other route is proxied to Ghost as normal
    location / {
        proxy_pass http://localhost:2368;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
    } 
}

The first two location blocks in the above file are the additions we made.

The first location block is acting as a standard http request, resolving with a static html file. It performs a direct match on the / route (the = sign is what causes it to only match /), and returns our custom landing page.

The second location block is acting as a "reverse proxy," which means it captures the incoming request on a particular route, and internally redirects that request to another web service (Ghost in our case) to fulfill the request, with the requesting client being unaware of any "redirect" being performed. This location block is also doing a direct match, this time on the /blog route, and proxy_pass'es to the ghost server to load the regular Ghost homepage.

The third location block will catch every other incoming http request that does not directly match / or /blog and internally proxies that to Ghost to fulfill the requests.

Note: Make sure to replace server_name codehangar.io with your domain.

Note: The second location must have the trailing slash in both /blog/ and proxy_pass http://localhost:2368/; This will strip out the /blog from the path before proxying it to Ghost. If you do not do this, Ghost will attempt to load a /blog route instead of your homepage at /. Thanks for this solution goes to http://serverfault.com/questions/444532/reverse-proxy-remove-subdirectory

Let us know if you have run into the same problem when wanting to put a static page at the root of your Ghost blog and if this solution works for you. Thanks and happy Ghosting!


About Author: Ian Grail
Ian Grail

Software Developer. Aspiring Pool Lounger.