How to Configure Ghost CMS Email with Mailgun (Full Guide)
A complete walkthrough for configuring Mailgun on your self-hosted Ghost instance, covering DNS setup, bulk newsletter delivery via API, and transactional email via SMTP.
Why Your Self-Hosted Ghost Instance Needs Email Configuration
If you've just spun up a self-hosted Ghost CMS instance, you might have noticed that certain things simply don't work out of the box. Try resetting your admin password and you'll get an unhelpful "copy error is not a function" message. Members trying to log in will see an endless spinner. That's because Ghost relies on email for core functionality, and without configuring it, your site is effectively broken for anything authentication-related.
Ghost handles two distinct types of email. Transactional emails are one-to-one messages like password resets, staff invitations, member signup confirmations, and magic login links. Bulk emails are one-to-many messages, primarily your newsletter sends. Each type requires its own configuration, even when you're using the same provider for both.
Understanding Mailgun Pricing (It's Cheaper Than You Think)
Mailgun's pricing page can be intimidating at first glance. You might see the $35/month plan for 50,000 emails and assume it's overkill for a small blog. The good news is that Mailgun offers 1,000 free emails every single month, and beyond that, they charge just $1 per additional 1,000 emails on a pay-as-you-go basis.
For most self-hosted Ghost users with a few thousand subscribers sending a handful of newsletters per month, you're looking at roughly $4–5 per month. That's not quite as cheap as Amazon SES, but it's very reasonable for a reputable sender with strong deliverability. It's also worth noting that Ghost Pro includes email sending in its subscription, which is one reason Ghost Pro gets more expensive as your contact list grows—they're absorbing that email cost for you.
Setting Up Your Mailgun Domain and DNS Records
The first step is adding a sending domain inside Mailgun. Rather than using your bare domain (e.g., yourdomain.com), Mailgun recommends using a subdomain like m.yourdomain.com. This keeps your transactional and marketing email reputation separate from your primary domain's email.
When creating the domain, choose your region (US or EU), toggle on the advanced DKIM settings, and opt for the longer DKIM key for better security. Mailgun will then present you with a set of DNS records to add at your DNS provider.
You'll need to create the following records: a TXT record for SPF verification, another TXT record for DKIM authentication, two MX records (only if you're using a subdomain, which you should be), and a CNAME record for open tracking. If you're using Cloudflare, make sure to turn off the proxy (orange cloud) for the CNAME record. Once all records are in place, hit the verify button in Mailgun. It may take a few minutes for everything to propagate, so don't panic if verification doesn't succeed immediately.
Configuring Bulk Email (Newsletter Delivery via API)
Bulk email is actually the easier of the two configurations because it's handled entirely through Ghost's admin interface. Navigate to Settings > Email newsletter (the gear icon), and expand the Mailgun configuration section. Select your region (matching what you chose during domain setup), then enter your subdomain (e.g., m.yourdomain.com).
Here's where a common mistake trips people up: you need the right type of API key. Do not go to Domain Settings > Sending APIs and create a new key there. While that key can send emails, it won't enable open and click tracking in Ghost—you'll see 0% open rates on every newsletter, which is alarming. Instead, click your user account icon in Mailgun, navigate to API Keys, and use the private API key listed there. You'll need to click the reveal icon to see and copy it.
After pasting the API key into Ghost and saving, head back to Mailgun's Domain Settings > Tracking section. By default, click tracking, open tracking, and unsubscribe tracking are all turned off. Toggle each one on so that Mailgun reports engagement data back to Ghost via the API.
Configuring Transactional Email (SMTP Setup)
Unlike bulk email, transactional email uses SMTP and requires editing a configuration file on your server. In Mailgun, go to Domain Settings > SMTP Credentials and create a new SMTP user. A name like "noreply" works well since these emails are automated messages like password resets that recipients won't reply to. After creating the credential, copy the generated password immediately.
Ghost's documentation provides a mail configuration template that you'll need to customize with your SMTP username (e.g., noreply@m.yourdomain.com) and the password you just copied. SSH into your server, switch to the ghost-mgr user, and navigate to your Ghost installation directory (typically /var/www/ghost). Open config.production.json with a text editor like nano, find the existing mail block, replace it with the configured template, then save and exit.
Finally, run `ghost restart` to apply the changes. If Ghost fails to restart, double-check your JSON syntax—a misplaced comma or missing bracket is the usual culprit. Once Ghost restarts successfully, test by triggering a password reset from the login screen. If the email arrives in your inbox, transactional email is working.
Testing and Verifying Your Email Configuration
With both configurations in place, it's worth running through a quick verification checklist. For transactional email, click "Forgot password" on your Ghost admin login page. You should see a confirmation message telling you to check your email, and the reset link should arrive within seconds.
For bulk email, open any draft post in Ghost, navigate to the email newsletter section in the sidebar, and send a test email to yourself. This uses the API connection rather than SMTP, so it validates an entirely different path. If both emails arrive successfully, congratulations—your self-hosted Ghost instance is fully configured for email delivery.
If you run into issues, the most common culprits are DNS records that haven't propagated yet, using the wrong type of Mailgun API key (domain-level vs. account-level), or a JSON syntax error in your config file. Ghost Pro users can skip all of this entirely since email is handled as part of the managed service.
Watch the Full Video
Prefer watching to reading? Check out the full video on YouTube for a complete walkthrough with live demos and commentary.