Painless Email Testing
Leo Sjöberg • October 2, 2015
For many applications that you build, there is always email involved. Often, this comes in the form of password resets and user verification. However, a recurring question is always "how do you test it". Do you just send the emails to a log file? Should you use a service like mailtrap.io, do you hook it up with your live server? The answer to all of the above is no (unless you're writing tests, in which case the log file is excellent for assertions). Instead, you run a local SMTP server. In the past, setting up your own SMTP server might have been an incredible pain, but nowadays, MailCatcher exists, and has made life a lot easier for many developers. Despite that, I won't recommend it. I'm not saying it's bad, but the installation is slow because, well, it's a ruby gem.
Introducing MailHog
MailHog is what local mail testing should be; easy, fast and requiring no installation. MailHog is built on Go, and comes as a precompiled executable which you just place on your local server, or if you're using Docker, simply use the dockerfile or run it from Docker Hub.
Installing MailHog (64-bit Linux)
Installing mailhog is incredibly easy; all you have to do is download the file and make it executable! However, then you might also want the service to start automatically whenever you start your local environment and whatnot. For that reason, some guy on the internet decided to make a shell script for it!
You can find the original shell script at https://gist.github.com/varghesejacob/68caf7aeee53305a1ffa#file-mailhog-bash-script and for convenience, it's right here too:
1#!/usr/bin/env bash 2 3echo ">>> Installing Mailhog" 4 5# Download binary from github 6wget --quiet -O ~/mailhog https://github.com/mailhog/MailHog/releases/download/v0.1.7/MailHog_linux_amd64 7 8# Make it executable 9chmod +x ~/mailhog10 11# Make it start on reboot12sudo tee /etc/init/mailhog.conf <<EOL13description "Mailhog"14start on runlevel [2345]15stop on runlevel [!2345]16respawn17pre-start script18 exec su - vagrant -c "/usr/bin/env ~/mailhog > /dev/null 2>&1 &"19end script20EOL21 22# Start it now in the background23sudo service mailhog start
Please note that this is for version 0.1.7 of MailHog. If a new version is released, edit the shell script before running it.
Hence, the definite easiest way to install MailHog is the following (supposing you are already SSH'd into your dev machine):
1$ wget -O mailhog-install https://gist.githubusercontent.com/varghesejacob/68caf7aeee53305a1ffa/raw/0e7efd5181d8d07ca45b3d81dd1239f3d7b0b2ec/Mailhog%2520Bash%2520Script2 3$ ./mailhog-install
That's all you need to get running. The script will install MailHog v0.1.7, make sure it starts on reboot, and then start the service.
Please note that this will not allow you to change any of the MailHog configuration, but will only use defaults; you will have to edit those afterwards.
Using MailHog
Once MailHog is installed, all you have to do is the following:
- Set your SMTP host to
localhost
- Set your SMTP port to
1025
To then access your mailbox, simply visit your dev server on port 8025
(note that you can of course also run the mail server locally in which case you would simply access localhost:8025
). In my case, my server exists at 192.168.10.10
, so I can access MailHog through 192.168.10.10:8025.
All emails you send are now sent to this mailbox. Note that accessing your server on port 8025 will always lead to mailhog, so you could also set up your local hosts file to point mail.dev
to your ip address, and could then access email via mail.dev:8025
.
Proxying for ease
Okay, so you don't want to have to type out the :8025
at the end of your domain all the time, or perhaps you just think mail.dev:8025
looks really ugly. Well, the good news are that if your dev server is on Nginx, setting up a proxy to forward to 8025 is incredibly easy! All you have to do is set up a new virtual host for your desired domain, I'll be using mail.dev
for this example.
- Create the host file
1sudo nano /etc/nginx/sites-available/mail.dev
- Well there, paste the following code:
1server { 2 listen 80; 3 server_name mail.dev; 4 5 location / { 6 proxy_pass http://192.168.10.10:8025; 7 proxy_set_header Host $host; 8 proxy_set_header X-Real-IP $remote_addr; 9 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;10 proxy_connect_timeout 150;11 proxy_send_timeout 100;12 proxy_read_timeout 100;13 proxy_buffers 4 32k;14 client_max_body_size 8m;15 client_body_buffer_size 128k;16 }17}
This will forward all your calls to mail.dev
to http://192.168.10.10:8025
. If you use another domain or another IP, make sure to change those.
Hopefully, you enjoyed this little read on mail testing, and will be able to use it for your own development!