Docker, PHP and E-Mail: getting things to work

Integrating Mailhog and SSMTP in your development environment

2,5'
Christian Bianchi 10/02/2017 04:21
category: DevOps

It’s a common need for software nowadays to send notifications through e-mail: registration confirmations, password recovery requests, event notifications and so on. As my colleagues develop software, they often encounter problems while dealing with such e-mail exchange in their local (Docker) environment.

The problem

Let’s say you are also developing a PHP application and you want to use docker in your development machine. You will notice that – if you use the official PHP images from the docker hub – sending e-mail out of the box simply won’t work. Lets’ see what I mean in practice, considering this simple index.php file, sending out an e-mail:

Please note: using the mail command to send an email is the simplest way, but there are many more powerful libraries out there that could make things easier. We have chosen to use the mail command just to keep the example as simple as possible.

If we run it using docker with the following command:

and visit http://localhost with our browser, we’ll see that the mail command will fail, and we’ll get an “Error sending the email” message.

The reason why this happens is that the “mail” command relies on the “sendmail” system command inside the container, which is missing from the official PHP docker image.

While you could simply create a new image extending the original one and adding the sendmail command, I suggest using a different strategy.

Here at MV Labs we do use a tool called Mailhog (https://github.com/mailhog/MailHog) which acts as an SMTP server listening on port 1025 but instead of sending real emails to your recipients, it simply displays them in a handy web interface (which is listening, by default, on port 8025). This way you avoid the risk of sending your testing e-mails to the customer (it happened at least once to everybody) and you don’t have to deal with spam filters or other annoyances in the e-mail chain.

So, how can we achieve this? To make things easier, we can take advantage of docker-compose. Let’s start by adding the mailhog container to our services:

Now, if we run docker-compose up and head our browsers to http://localhost:8025 we should see the mailhog simple but powerful web interface.

We’re not done yet, though, as we still need to tell the mail command to send emails through our new mailhog smtp server. Unluckily this requires the building of a custom docker image, since PHP doesn’t allow using the native mail command to connect to a SMTP server. For this reason, we need a tool called ssmtp (https://linux.die.net/man/8/ssmtp) which is basically a configurable sendmail command replacement, and which forwards the message to a SMTP server configured in its config file. We’ll need the following Dockerfile:

Then we’ll need to tell docker-compose.yml to build the image from the Dockerfile for our PHP container:

and build our containers again with:

Now we’re ready to send our first “virtual” email. Just head your browser to http://localhost and you’ll get the message “Email sent correctly”. If you check your mailhog at http://localhost:8025 you’ll see your email!

Summary

Using a simple example, we have demonstrated one possible solution for sending test e-mails out of our web applications under development in a secure and handy way, by using some nice open source tools such as SSmtp and Mailhog inside a docker dev environment.

Let us know what you think in the comments area below and happy developing!

Posted by Christian Bianchi

Follow @whites11 on twitter.

Leave a comment

Your email address will not be published. Required fields are marked *

*

*