Skip to main content

Using Postfix with WordPress and wp_mail()

In this lesson you will make sure your WordPress site can send email through your Postfix relay setup. You will first configure and test PHP's mail() functionality, then customize the WordPress wp_mail() behavior. You will verify SPF and DKIM alignment, and general email health and deliverability using Mail Tester.

PHP and mail()

Now that we have a local Postfix service up and running, and we've tested our ability to deliver email from the command line using sendmail, let's make sure that translates into our PHP configuration.

By default, PHP's mail() function is simply a wrapper around the sendmail binary. Make sure the sendmail_path configuration option is set correctly:

php -i | grep sendmail_path

sendmail_path => /usr/sbin/sendmail -t -i

This is usually the default, but if it is not set, or set to the wrong binary, you can change this in your /config/php/php.ini file for all sites. If you do change this value, don't forget to restart php-fpm.

Let's create a sample mail-test.php script to send ourselves an email:

<?php
mail( '[email protected]', 'Hello', 'From PHP' );

Run the script using the php CLI:

php mail-test.php

Make sure the email lands in your inbox (or spam folder). If it's still missing after a few minutes, look for clues in your mail.log and your third-party SMTP log provider.

WordPress and wp_mail()

If mail() is working correctly, chances are the WordPress wp_mail() function will also work as expected. However, WordPress uses the PHPMailer library under the hood to compose the message before sending it off to mail(). This allows us to use various filters to customize the outbound email.

I like to set these in a must-use plugin for each site individually. Let's create a new plugin file:

cd /sites/uncached.org/public_html/wp-content/
mkdir mu-plugins
touch mu-plugins/mail.php
sudo chown -R www-data:www-data mu-plugins

Edit the new plugin file. Here's the contents of mine:

<?php
add_filter( 'wp_mail_from', function() {
    return '[email protected]';
} );

add_filter( 'wp_mail_from_name', function() {
    return 'Karl Kubelet';
} );

The filters are self-explanatory. The first one sets the From address, while the second one sets the name. This will work with most third-party SMTP providers, however, some might require an additional Sender header, which may be set using:

add_action( 'phpmailer_init', function( $phpmailer ) {
    $phpmailer->Sender = '[email protected]';
} );

If not set, this defaults to the www-data@ address with your Postfix origin, which will show up in your email logs. I like to set this, even if it's just for cosmetic purposes.

Now with this plugin in place, let's invoke a WP-CLI shell and send ourselves an email. You can run the interactive shell using the wp shell command:

This article is for premium members only. One-time payment of $96 unlocks lifetime access to all existing and future content on wpshell.com, and many other perks.