MyLocalDev Part 3: MailHog and mhsendmail on OS X

Published 2 months ago on September 28, 2017 — 3 min read

There was one a time where I was working on a project. This project involved making edits to a site that had been live for some time, but was due for a few updates. I did what I always do and updated my dev environment first via git and pulled down a copy of the site contents using WP Migrate DB Pro.

A few minutes later I got a notice that my ESP (email service provider) credits had been depleted.

🚨 NOT GOOD 🚨

As it turns out, I had inadvertently initiated a gigantic backlog of emails that had already been sent out from production, but with the move to dev everything got triggered again.

I learned my lesson that day, I learned it the hard way. My first reaction was to take advantage of wp_mail being pluggable and just use an mu-plugin to prevent sending of any mail, but that proves to be annoying when you actually do want to test emails.

Someone much smarter than me came up with the idea of a server-level application that essentially hijacks everything email such that you can test email sending without actually sending email. It’s a win-win. Local by Flywheel has MailCatcher built in which works wonders, but I found it challenging to install in my local Valet-powered MEMP stack.

Enter MailHog

I found MailHog and I love it. It’s inspired by MailCatcher but I found it a bit more straightforward to get up and running given my local setup in Valet.

Installing MailHog is easy thanks to Homebrew:

brew install mailhog

That’s it. MailHog is now up and running locally on http://127.0.0.1:8025/, but integrating it with Valet took a couple more steps.

Using mhsendmail as a sendmail alternative

With MailHog up and running it’s essentially a server waiting to receive emails, you still need to configure your environment to send those emails to MailHog. I wanted my setup to be foolproof. My local server will never really need to send a proper outgoing email (nor do I want it to) so I found the most blatant way to ensure PHP itself was sending directly to MailHog, no excuses.

mhsendmail was designed as a full-on replacement for sendmail (which is responsible for sending email). Installation is a bit different than what you may expect as it’s powered by Go, but executing the following commands will get mhsendmail installed and running:

brew install go

go get github.com/mailhog/mhsendmail

The installation process involves creating a go folder in your home directory, which acts as a bucket for anything installed via go get. Simple enough.

You’ll need the path to the mhsendmail binary that was installed in the go folder within your home directory, mine looks like this:

/Users/jchristopher/go/bin/mhsendmail

In order to have PHP send email via mhsendmail which makes the connection to MailHog, we need to edit our php.ini. To find out where your php.ini is located (the one used by Valet) execute the following command:

php -i | grep 'Loaded Configuration File'

Which will output something like this (the exact path may be different on your machine):

Loaded Configuration File => /usr/local/etc/php/7.1/php.ini

Open up your php.ini and find sendmail_path (it’s likely commented out) and replace it with the following, ensuring the path is that of your mhsendmail binary:

sendmail_path = "/Users/jchristopher/go/bin/mhsendmail"

The last step is to restart Valet which in turn loads this configuration:

valet restart

Once that’s done, MailHog will trap all emails sent through PHP from your Valet powered MEMP stack!

Read more from this series

This article is part of a MyLocalDev series all about local web development on OS X. Check out the other articles in this series:

Copyright © 2006—2017 Jonathan Christopher