How to set up basic email sending with Ghost and Gmail SMTP

I previously wrote about how to Host a Ghost Blog on Google Cloud for Free. What I wasn't aware of at the time and didn't cover in that article is that Ghost requires additional configuration to send emails for user invitations, notifications, and password resets among other things. This article will cover how to set up Ghost to send email through Gmail SMTP.

SMTP Server vs SMTP Relay

Two options are available for routing email through Gmail. Free Gmail users and Google Workspace users alike can use the standard SMTP Server setup to route email. If you have ever set up Gmail's Outgoing Mail Server with an email a client, then you should already be familiar with this setup.

If you are a Workspace user, you additionally have access to SMTP Relay which can be configured to authenticate emails with IP addresses to add an additional layer of security. Whichever method you choose, you'll first need to generate a dedicated app password.

Generate an App Password for Ghost

  1. Log in to your Gmail or Workspace account, then open https://myaccount.google.com and navigate to Security > Signing in to Google > App passwords.
  2. Click Select app, choose "Other", and provide a name (e.g. Ghost SMTP)
  3. Click Generate, then copy down the password exactly as written and keep it handy.
⚠️
You will only have once chance to write down the password. If you miss this step or made a mistake, then delete the password and start over.

Set up SMTP Server for Ghost

Login to your VM instance via the Google Cloud Console by clicking SSH in the row of the instance you want to login to.

Configure Ghost email settings

Ghost uses Nodemailer to send emails, and the configuration for Nodemailer can be found in the Ghost config.production.json file.

# Navigate into your installation direcctory
cd /var/www/your_site_name

# Edit Ghost config
sudo nano config.production.json

The ghost configuration file may contain a default mail block. Comment out or remove the default configuration if it exists, an replace it with the following config.

  "mail": {
    "from": "your_email_address",
    "transport": "SMTP",
    "options": {
      "host": "smtp.gmail.com",
      "port": 587,
      "auth": {
        "user": "your_email_address",
        "pass": "your_app_password"
      }
    }
  },

Save your configuration file and run ghost restart to apply the updated configuration. After Ghost has restarted, open a new Incognito window and point your browser to yourdomain.com/ghost to open the login page. Type in your username and then click Forgot in the password box. If everything was configured correctly, you should receive a password reset email in your inbox.

💡
After you've confirmed that Ghost is able to send transactional emails successfully, be sure to destroy the paper you wrote your password on for security.

(optional) Send email with SMTP Relay

If you use Google Workspace and want to add an additional layer of security, then follow the Workspace Admin instructions to set up SMTP Relay for your workspace account.

Configure SMTP Relay Service Settings

  • Allowed Senders: Select "Only registered Apps Users in my domains"
  • Authentication:
    • Check "Only accept mail from the specified IP addresses" and configure it to your VM instance's external IP address
    • Check "Require SMTP Authentication"
  • Encryption: Check "Require TLS encryption"

Update Ghost configuration to use SMTP Relay

Open your config.production.json file and update the configuration to be similar to the following code block.

  "mail": {
    "from": "your_email_adress",
    "transport": "SMTP",
    "options": {
      "name": "your_hostname_or_arbitrary_string",
      "host": "smtp-relay.gmail.com",
      "port": 587,
      "auth": {
        "user": "your_email_address",
        "pass": "your_app_password"
      }
    }
  },
💡
The default hostname value that Nodemailer sends for EHLO handshake is an invalid value for SMTP Relay and will cause email sending to fail. For this reason we manually set the hostname using the name option. I use my instance's hostname, but it appears any arbitrary string will work.

Once the configuration has been updated, be sure to run the ghost restart command to apply the updated configuration, then try sending yourself another password reset link to make sure that emails can be successfully sent.