How to set up Ghost CMS behind your own reverse proxy

Let's look how to set up correctly your Nginx reverse proxy and Ghost CMS to work completely through HTTPS.

How to set up Ghost CMS behind your own reverse proxy
Photo by Taylor Vick / Unsplash

When setting up this instance of Ghost CMS, I was faced with a little problem regarding my network config on my dedicated server. I use several VMs connected to a router VM which distribute the internet connection. One of those VMs receive all of the traffic for 80 & 443 ports, it's my Nginx reverse proxy which itself proxies the connection to the differents "servers" VMs.


As you might have guessed, one VM runs a Linux distro which powered Ghost CMS. The distro used is Ubuntu as it's the one used in the Ghost doc (and most likely the best supported one).

The way Ghost CMS works is with a nodeJS app that generates all the files and serves them through the 2368 port by default. It doesn't listen to 80 or 443 for simplicity and security reasons. That's why the documentation require a nginx install on the host to proxy to 127.0.0.1:2368. That way, it's nginx that handle as a reverse proxy all the SSL handshake if you want to use HTTPS (use it!).

And that's where the trouble begins for my config because it would mean reverse proxy over reverse proxy which doesn't play nice with HTTP redirect and preview functionality of Ghost CMS.

If you already have installed Ghost CMS and the stack needed for it. Chances are that you have installed Nginx prior to Ghost and you entered the domain of your website when asked during the setup. You might even have used HTTPS during this setup. Behind a reverse proxy, entering the HTTPS would have most likely failed.

Now, you have Ghost CMS installed with the local Nginx configured. Your first instinct would be to configure the main Nginx to proxy to the Ghost one. You can access your website this way but a problem is quickly discovered if you have set up SSL certificates on your main Nginx (and so you access the website through HTTPS). You can't have any website preview inside the admin dashboard because Ghost CMS try with HTTP and it can't handle the redirect.

Blank preview in the admin panel

The solution is to bypass the local reverse proxy and use only your main reverse proxy to Ghost. The catch is that Ghost CMS listen for connection on 127.0.0.1:2368 which is not accessible by your main Nginx. You have to instruct Ghost to listen on 0.0.0.0:2368.

Now, let's do all those configs.


Connect to the server hosting your main reverse proxy.

First, create a config file in /etc/nginx/sites-available/

You can name it however you want but I use the domain it listen for as a filename like many Nginx administrator. (e.g. blog.causticlabz.net)

In your config file put the following config:

server {
	# Replace all instance of blog.causticlabz.net with your own domain
    
    listen 80;
    listen [::]:80; # If you use IPv6
    
	server_name blog.causticlabz.net;
    
    access_log /var/log/nginx/blog.causticlabz.net.log;
    
    client_max_body_size 50M; # Enable file upload with a limit of 50Mb
    
    location / {
    	include proxy_params; # Include proxy paramaters needed, the same as the one explicitly written by Ghost CMS config
        proxy_pass http://192.168.1.2:2368$request_uri; # Replace with the IP of your server hosting Ghost CMS
    }
}
Note that I configure listening on 80 port. I use Let's Encrypt for my SSL certificates setup and it handles automatically the creation of the HTTPS part.

Because Nginx use two folders containing the config files for available and enabled sites, we have to put the config file to the enabled folder too. You could copy it but it means two files to maintain so we'll create a symbolic link to have one file present in the two folders.

sudo ln -s /etc/nginx/sites-available/blog.causticlabz.net /etc/nginx/sites-enabled/blog.causticlabz.net

To set up your SSL certificates with Let's Encrypt, first install "Certbot" if you don't have it already.

sudo apt install certbot python3-certbot-nginx

Now, use Certbot to configure your certificates.

sudo certbot --nginx -d blog.causticlabz.net

Replace with your domain, note that if you use www subdomain, you have to add to the command "-d www.yourdomain.com" or any other domains and subdomains to set up.

Certbot will also automatically renew the certificates when they're about to expire. If it's the first time you use Certbot, it will ask for an email address to send alerts if needed then ask you to accept the EULA.

Certbot will ask how to set up the config file for nginx, if it needs to enable the redirection or not. Of course, the whole point in this exercise is to have the redirection enabled. So choose accordingly.

Certbot will then proceed to contact Let's Encrypt server, set up SSL certificates and adding them to your nginx config.

Everything is good for your main reverse proxy.


Time to configure Ghost CMS. Connect to the server hosting it.

Change directory to the one hosting your Ghost CMS. Then, do the following command:

ghost config set server.host 0.0.0.0

That's it! Now you should be able to access your instance of Ghost CMS through HTTPS with everything working correctly inside it. If you have any questions or comments, do not hesitate to contact me. Now it's time to start writing some articles on your CMS!