If you’re running your own webserver and expect it to send email via PHP mail() without issue, you are going to have a bad time.
Since I wrote this article in 2017, email providers have become very strict on who they will receive email from. Back in 2017, the massive email services such as Gmail and Office 365 would reluctantly accept emails from cloud instances such as DigitalOcean.
I have observed over the past years a tightening of spam filters, preventing PHP mail() emails from ever reaching their recipients, despite checking all the boxes my end.
So, while this guide will indeed enable your server to send emails out into the ether, the problem now is whether the receiving mail servers will accept or reject them.
Personally, I now relay all emails through a mail provider, be it Mailgun, Sendgrid, or Gmail. You can configure Postfix to send email through an SMTP provider of your choice, which is now my recommendation to guarantee mail delivery.
Please see Step 5 below if your test PHP mail()s are not being delivered to your recipient.
1. Install Postfix
Let’s update the package database first.
sudo apt-get update
mailutils, which will automatically install Postfix.
sudo apt install -y mailutils
If you see the information screen below, select OK by pressing
Select Internet Site and press
System mail name should be your domain name eg.
Package should now be installed.
2. Configure Postfix
For security reasons, you should instruct Postfix only to process requests to send emails from the server on which it is running.
Edit the Postfix configuration file.
sudo nano /etc/postfix/main.cf
Towards the bottom of the file, find the line
inet_interfaces = all. (Press
W to search)
Change it to:
inet_interfaces = loopback-only
Save file and exit. (Press
Y and then press
Lastly, let’s restart Postfix.
sudo systemctl restart postfix
If you intend on sending email to your own domain, Postfix requires some additional configuration. For example, I want my PHP app to send emails to [email protected]. This will fail if you don’t make some additional changes to your
3. Test Postfix
We’ll now send a test email message. Make sure to replace
[email protected] with your own email address.
echo "Test Email message body" | mail -s "Email test subject" [email protected]
Don’t forget to check your spam folder.
If you still haven’t received any mail after a few minutes, check the mail error log.
sudo tail /var/log/mail.log
If the mail log is empty or doesn’t give enough information, try parsing the syslog. This will return the last 50 entries for postfix.
sudo tail -f -n 50 /var/log/syslog | grep postfix
If the syslog is empty and you still haven’t received any test email, it’s possible that the test email was rejected by the recipient server. You should check to see if anything has bounced back to your mail folder.
sudo less /var/mail/$(whoami)
G to scroll to the bottom of the file and lowercase
q to quit. The
$(whoami) variable returns the currently logged in user.
UPDATE Feb 2020: If you are sending to Gmail, Outlook or other large email providers, you may get a bounce error. Please see Step 5 below for possible solutions.
4. Test PHP mail()
If Postfix is working correctly, you should now be able to send mail via PHP
<?php $to = '[email protected]'; $subject = 'the subject'; $message = 'hello'; $headers = 'From: [email protected]' . "\r\n" . 'Reply-To: [email protected]' . "\r\n" . 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, $headers); ?>
5. Mail Never Received / Spam Issues
If emails are being rejected by the remote mail provider (such as Gmail or Office 365), or mail is going straight to your email client’s spam folder, you may need to do some additional configuration on your domain (SPF, DKIM, DMARC records) to get past spam filters. Please see:
- Postfix Gmail Bounce: This message does not have authentication information or fails to 550-5.7.26 pass authentication checks.
- Another error I have seen from Gmail’s mail server is due to my server’s IP being blocked:
status=bounced (host gmail-smtp-in.l.google.com said: 550-5.7.28 Our system has detected an unusual rate of 550-5.7.28 unsolicited mail originating from your IP address. To protect our 550-5.7.28 users from spam, mail sent from your IP address has been blocked.
You may never be able to guarantee delivery of mail via Postfix if you do not route mail through a trusted, external SMTP server. Having had many issues myself over the years sending PHP mail()s from my own cloud server, my recommendation now is to relay mail from Postfix to an external SMTP provider in order to guarantee delivery.
- Relay Postfix PHP mail() messages through an external SMTP server.
- Relay Postfix PHP mail() messages through Gmail’s SMTP server.