How to Force https with Ghost

Photo by Meritt Thomas / Unsplash

Alright so I set everything up in my last post and everything was working just fine until I went to set up ghost memberships on and the signup process wouldn't work.

Ghost is using a cool passwordless approach to authentication. That means no passwords for anyone to remember! This eliminates the potential for any password data theft and thus limits the liability of site owners.

It also means that you login with your email only, then you have ten minutes to check your email, and click that email to get the appropriate JSON web tokens (JWT) for authentication.

It's a cool work around for passwords but it turns out it relies strongly on the Stripe and Mailgun integrations to effectively serve the JWT.

I clearly didn't configure my base URL properly and Stripe was refusing the request over http, so I had to find a way to force https.

I was googling and googling and going down a rabbit hole of complexity and things I didn't really want to have to do. Until I luckily stumbled across this documentation that was in front of my eyes the whole time.

It turned out to be a lot simpler than I initially thought it would be. Now I have to double check my Mailgun configuration because the email isn't getting through but that's a new post in the near future.

Here's what I did (you may want to review my last post if it doesn't make sense).

Step 1: Login to Your Droplet/Server

For beginners the '$' in these can be omitted, it's just a common way to write out the input of the terminal.

$ ssh root@your_server_ip

Step 2: Login to the Appropriate User

In that last post my first user was called sammy, and my second user for my second site was named janey but you should replace either with the username that you used to set up the domain you need to change.

If I wanted to change the configuration of my first site it'd look like this:

$ su - sammy

You should see your command line prompt change to something like:


Step 3: Find the Appropriate Domain Configuration

If you know it (I have mine written down) you can simply navigate right into that directory:

$ cd /var/www/[nameofdomain]

If you forget or simply want to see what domains you have configurations for:

$ cd /var/www

To list the directories on your screen it's a simple command that everyone should know:

$ ls

Step 4: Run the Ghost-CLI Commands

From here on down it's basically just following that ghost documentation:

$ ghost config url https://[yourdomain].com

Then if you didn't set up your ssl in that last article for some reason you'd run:

$ ghost setup nginx ssl

This is to set up the ssl but we already did, so running that command is redundant and won't do anything else.

Step 5: Restart Ghost

Simply run:

$ ghost restart

You'll probably have to enter your user password and you're not done yet but you're close.

Step 6: Set Up a www. SSL Nginx Config

This is a little buried based on our previous set up and you won't be able to just adjust your global Nginx configuration.

The way we configured multiple ghost domains on one digital ocean droplet is that we use the ghost-CLI tool to generate a Nginx config file for each domain.

Note: You'll still need to be logged into the appropriate user you set up for any individual domain you want to force https to. Meaning you'll have to do this for each individual domain under each different user you've associated with that domain.

My Problem

The problem that I ran into after doing the above was that if I typed in or googled specifically and it would give you a warning that this was insecure.

This was despite setting up my www A name properly on Digital Ocean and seems be a minor flaw in how the ghost-CLI tool sets SSL up on your behalf.

Type in and it was redirecting properly to Type in and it would also redirect properly, it was just that one specific path.

Happy Path: How likely is it these days that a user will explicitly type in

Probably not that likely, but if it was showing up strangely on Google I still didn't want to risk it. Especially on any of my other sites where https is even more important because they are taking money via Stripe.

The next step was to follow along to this section of the ghost documentation.

"You may wish to have multiple domains that redirect to your site, e.g. to have an extra TLD or to support www. domains. Ghost itself can only ever have one domain pointed at it. This is intentional for SEO purposes, however you can always redirect extra domains to your Ghost install using nginx. If you want to redirect an HTTPS domain, you must have a certificate for it.

Basically we have to set up a second SSL to www.[yourdomain].com and we do that like this from your /var/www/[nameofdomain] file so that you have access to ghost commands:

$ ghost config url https://www.[yourdomain].com

Don't worry, this will not restart Ghost or alter your https://[yourdomain].com configuration. You're merely switching over to a new config from within your domain file. You should see something like:

Successfully set 'url' to 'https://www.[yourdomain].com'

And I believe (though I'm not 100% sure) that because each user only has permissions for each domain that this is partly why the following commands will all end up where they are supposed to. 🤞

Next, get Ghost-CLI to generate another SSL setup for you:

ghost setup nginx ssl

You’ve now got two domains setup with SSL. The main canonical domain, and your www. domain.

Now change back to your canonical (main) Ghost config back before you forget.

ghost config url https://[yourdomain].com

Step 7: Change Your Ghost Nginx Config Files

Finally, you’ll need to edit the Nginx config files for your main canonical and your new www. domains to redirect properly.

*Note: The first time I published this article, I had only changed the [yourdomain].com.conf, which explains why the other redirects worked as they should.

Edit both /system/files/www.[yourdomain].com.conf and /system/files/my-[yourdomain].conf to redirect properly:

$ nano /system/files/www.[yourdomain].com.conf

Right under the server_name in the server object add the following:

server {    
    return 301 https://[yourdomain].com$request_uri;

Repeat with the other config file:

$ nano /system/files/[yourdomain].com.conf

And make the same change under the server_name in the server object:

server {    
    return 301 https://[yourdomain].com$request_uri;

Once you have made those changes run sudo nginx -t to get nginx to verify your config, and sudo nginx -s reload to reload nginx and pick up your new configuration.

Step 7: Finalize All Your Changes

Now use Nginx to verify your new configuration

$ sudo nginx -t

And reload your Nginx with the new configuration

$ sudo nginx -s reload

And you may as well restart ghost again just in case:

$ ghost restart

Wrapping Up

Well that turned out to be a lot easier in the end than I anticipated. That's always a nice surprise. signup is no longer spinning and giving me an error in the developer console. And hopefully I've resolved any and all straight redirects from unsecured http.

I get the confirmation that an email was sent:

My new problem is that the email is nowhere to be found!

Time to debug Mailgun...

Update: Fixing the https and restarting everything fixed the Mailgun issue. I suspect serving it over http initially meant Stripe wouldn't authenticate which meant it was never getting to Mailgun.

Darren Beattie

Read more posts by this author.