How To Set Up Transactional Emails in Ghost

I no longer use Ghost for this site

When I was setting up this blog, I ran into two issues related to users subscribing to my newsletter:

  1. For some reason, the sign-up form would throw an error when trying to subscribe with Gmail addresses and
  2. The 'Confirm your subscription' emails were going to spam

After lots of time going down rabbit holes, I finally found a solution and this post is going to walk you through it.

When you set up Ghost on your own server instance (i.e. not through Ghosts hosting solution), transactional emails use some default settings that aren't ideal. Even if you set up the Mailgun API for bulk email from the CMS, transactional emails are dealt with separately and require you to do some extra work.

In short, here is what you need to do:

  1. Check you have an spf record on your domain DNS
  2. Update your config.production.json file on the server to send transactional emails via SMTP (here I use Mailgun as it is required for bulk email and is pretty easy to set up)

Let's take a look at these two steps in more detail below but before we do, note that these steps are based on my own set up.  The below steps may vary if you are using different providers.

For refernce, I self-host Ghost using a Digital Ocen droplet and my email service provider is Mailgun (for both bulk and SMTP/transactional emails).

Step 1: Add an SPF record to your domain DNS

When you add an SPF record to your domain, you are effectively telling email services like Gmail and Yahoo that you have given your email service provider (e.g. Mailgun) permission to send emails from your domain. Without this, your emails will likely be flagged as spam and your users might never see the email.

To fix this, go to your domain host and check the DNS settings on your domain. Mailgun should have shown you how to do this when you set up your account with them but if not, you can see how mine looks below.

(Note, I am using a subdomain 'mg' to send emails from. This can be good practice so that your root domain doesn't get added to the spam list for whatever reason).

That is it. Obviously, if you use a different email service provide to Mailgun, you should change the include=mailgun.org part to reflect that provider.

Step 2: Update your config.production.json file

This section involves a little more work. We now need to update our Ghost instance to send transactional emails via SMTP using Mailgun. Let's take it step by step.

First, you need to access your Ghost instance using SSH from your own terminal. If you don't have SSH set up, check out this tutorial from Digital Ocean.

In your terminal, SSH into your instance by running the following command:

ssh root@<YOUR WEBSITE IP ADDRESS>

( you can get your IP address from inside the Digital Ocean Dashboard by opening the droplet and copying the number next to ipv4)

Next, we need to go to the directory where Ghost is installed:
cd /var/www/ghost

Here is our config file and we need to edit it using Vim:

vim config.production.json

Once the file has opened, hit i to enter insert mode so you can start editing it.

Here we have to update the mail settings in the config file to use SMTP and the credentials from our Mailgun account. To do that, you need two pieces of data from Mailgun:

  1. Your SMTP login: normally postmaster@yourdomain.com (to find it, click 'Sending' in the left panel, then 'Domain Settings', then go to the SMTP Credentials Tab)
  2. Your API Key: shown as your 'Private API key' in the Account Security page

Going back to terminal, you need to update your config file to the following (adding your own user and pass details):

{
  "mail": {
    "transport": "SMTP",
    "options": {
      "service": "Mailgun",
      "host": "smtp.mailgun.org",
      "port": 465,
      "secureConnection": true,
      "auth": {
        "user": "postmaster@<YOUR DOMAIN>",
        "pass": "<YOUR API KEY>"
      }
    }
  }
}

Note that the port is 465. This is different from what the official Ghost docs suggest. I followed the Ghost docs first and it didn't work until I went with 465. H/T this forum response by the user morgan which saved my ass here.

Save and exit from Vim by pressing esc then wq and hitting enter.

Finally, you need to restart Ghost by running the command ghost restart. If you are on the root user it will initially say that root users can't run commands but it goes ahead and does it anyway.

Finishing up

With all that set up, transactional emails should now be working an emails shouldn't be headed to spam.

I hope you found this useful and that the numerous hours I lost working all this out will save you some time.

I will be regularly posting the steps I am going through as I try to build an online business so if you found this useful and are going through a similar process you can sign up below this article.

Useful Links: