How to install mailcatcher on CentOS 7 and configure it for PHP

The problem

Handling outgoing emails in a web application can be hard, because it’s very easy things to get wrong and send unwanted test mails to real world customers while testing some functionality.
Ensuring sent emails are designed, parsed and formatted correctly is a painstaking problem, too.

… and the solution

Mailcatcher is a program you can use to test sending email. It gives you the ability to inspect sent emails and their headers. It is a simple SMTP server that can receive emails. It also gives you a nice web interface to preview the sent emails.

We’ll cover installing the dependencies for Mailcatcher. Then we’ll install and set it up for easy use in our development environment. This includes use with PHP. Finally, we will setup password protect subdomain for easier access using Nginx.

Setup

First update yum’s repository list, then install the gcc and g++ compilers, and MailCatcher’s dependencies (Ruby and SQLite).

yum update
yum -y install gcc gcc-c++
yum -y install sqlite-devel ruby-devel

Now install and MailCatcher itself.

gem install mailcatcher

Running MailCatcher

Once installed, you can run mailcatcher –help to see what options are available.

Start MailCatcher by running mailcatcher –ip [your-vultr-ip-address] on your terminal. Use 0.0.0.0 to bind to all interfaces. Your output should look similar to the following:

root@install:~# mailcatcher --ip [your-ip-address]
Starting MailCatcher
==> smtp://127.0.0.1:1025
==> http://127.0.0.1:1080
*** MailCatcher runs as a daemon by default. Go to the web interface to quit.

NB: If MailCatcher’s web interface fails to load, then you may have to open port 1080 and enable “http service” on CentOS firewall.

One possible solution is to run the commands bellow to open port 1080 for inbound connections or scroll down and read how to setup nginx proxy and access the mailcatcher web interface on port 80 as regular web site.

firewall-cmd --zone=public --add-port=1080/tcp --permanent
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload

Start on Boot

It is useful to setup Mailcatcher to start when the server boots. This lets us forget about having to turn on Mailcatcher whenever we start our development machine.

Rather than install a process monitor, we can use systemd, which currently comes out of the box with CentOS 7.

Create and edit file /etc/systemd/system/mailcatcher.service

Put in the following contents and save the file:



[Unit]
Description=Ruby MailCatcher
Documentation=http://mailcatcher.me/

[Service]
Type=simple
ExecStart=/usr/local/bin/mailcatcher --foreground --http-ip=0.0.0.0
Restart=always

[Install]
WantedBy=multi-user.target

Reload systemd to see the changes

systemctl daemon-reload

Start the mailcatcher service:

systemctl start mailcatcher

Start the service at boot:

systemctl enable mailcatcher

Configure PHP to use Mailcatcher

PHP needs the php.ini configuration sendmail_path set to the path of sendmail. Mailcatcher comes with the catchmail command, which can be used for this purpose.

We’ll add a new configuration in PHP’s /etc/php.d/ directory. Then we’ll enable that configuration for each of PHP’s SAPIs (command line, within PHP-FPM, or loaded in Apache).

# Add config for PHP 
echo "sendmail_path = /usr/bin/env $(which catchmail) -f test@local.dev" | tee /etc/php.d/mailcatcher.ini

# Restart Apache if using mod_php
service apache2 restart

# Restart PHP-FPM if using FPM
service php5-fpm restart

You can test the installation using the following command:

php -r 'mail("info@vladimir-ivanov.net", "Feedback", "This is so useful, thanks!");'

Setup password protected (sub)domain for easier access

First, you need to edit /etc/nginx/nginx.conf and the following directive in order to allow Nginx to proxy websockets, too:


http {

    # ....
    # As suggested in http://nginx.org/en/docs/http/websocket.html
    map $http_upgrade $connection_upgrade {
    default upgrade;
    "" close;
    }

    # ....
}

The next step is to create new virtual host file, for example /etc/nginx/conf.d/mailcatcher.site.com.conf with the following contents:

server {
    listen 80;
    server_name mailcatcher.site.com;

    location / {
        proxy_pass              http://127.0.0.1:1080;
        proxy_http_version      1.1;
        proxy_set_header        Upgrade $http_upgrade;
        proxy_set_header        Connection $connection_upgrade;
        auth_basic              "Development server. Restricted access.";
        auth_basic_user_file    /etc/nginx/.htpasswd;
    }
}

You can create new .htpasswd file using the following command

 htpasswd -c /etc/nginx/.htpasswd exampleuser

Enjoy!