Introduction
In this article, we’ll install and configure Postfix so PHP’s mail()
function can send email on a Linux server. We’ll cover distribution-specific instructions for Ubuntu/Debian (using apt
) and CentOS/Fedora (using yum
or dnf
). The same principles apply to most modern Linux distributions.
Because many email providers now aggressively block or flag messages that aren’t authenticated or come from unknown IP addresses, relying only on a basic server mail setup can lead to poor deliverability. For more reliable results, consider relaying mail through a well-known SMTP service such as Mailgun, Sendgrid, or Gmail.
This guide will enable local sending of emails from your server. However, whether the receiving mail servers accept your messages depends heavily on DNS records (SPF, DKIM, DMARC) and your IP reputation. If your test emails don’t arrive, see Step 5 for troubleshooting tips.
Step 1: Install Postfix
Debian/Ubuntu-based distros
You can install Postfix directly, or optionally install mailutils
for convenient command-line testing. If you only need Postfix for PHP mail, mailutils
is not strictly required.
sudo apt-get update
Option A: Install only Postfix
sudo apt-get install -y postfix
Option B (Optional): Install mailutils
(which also includes Postfix if not present)
sudo apt-get install -y mailutils
During the Postfix setup prompts, choose Internet Site if you plan to send emails externally. For the System mail name, enter your domain name (e.g., example.com
).
CentOS/Fedora/RHEL-based distros
Use yum
or dnf
. (Replace dnf
with yum
if your system doesn’t have dnf
.) The mailx
package is similar to mailutils
for Debian/Ubuntu, providing the mail
command.
sudo dnf install postfix -y
(Optional) install mailx
for command-line testing.
sudo dnf install mailx -y
During the Postfix setup prompts (especially on Debian/Ubuntu), choose Internet Site if you plan to send emails externally. For the System mail name, enter your domain name (e.g., example.com
).
Step 2: Configure Postfix
For security, configure Postfix to listen only on the local interface if you do not intend to receive mail from the internet. This reduces the risk of your server being used as an open relay.
Edit the Postfix configuration file:
sudo nano /etc/postfix/main.cf
Look for or add this line to limit Postfix to localhost only:
inet_interfaces = loopback-only
Save and exit (press CTRL
+ X
, press Y
, then press ENTER
)
Next, restart Postfix:
sudo systemctl restart postfix
sudo systemctl enable postfix
If you plan to send mail to local users at the same domain as your server (e.g., [email protected]
), you may need further configuration so Postfix recognizes and delivers these messages locally. Consult your distribution’s documentation or this guide for more details.
SELinux / AppArmor note: On SELinux-enabled systems (CentOS, Fedora, RHEL), you may need to allow web processes to send mail. For instance:
sudo setsebool -P httpd_can_sendmail on
On AppArmor-based systems (e.g., Ubuntu/Debian), ensure /usr/sbin/sendmail
and postfix
are permitted in your web server’s AppArmor profile.
Step 3: Test Postfix
If you installed mailutils or mailx, you can send a test email from the command line to confirm Postfix is working. Replace [email protected]
with your own email address:
echo "Test Email message body" | mail -s "Email test subject" [email protected]
Check your inbox (including spam/junk folders). If you don’t see the message, review the mail logs:
sudo tail /var/log/mail.log
On some systems (including many CentOS/Fedora setups), the logs are found in /var/log/maillog
. Or use this to monitor syslog for Postfix entries:
sudo tail -f -n 50 /var/log/syslog | grep postfix
If you still don’t see the email, check for bounce messages in your local mail spool:
sudo less /var/mail/$(whoami)
Step 4: Test the PHP mail()
Function
Next, verify that PHP’s mail()
function successfully hands off mail to Postfix. Create a simple PHP test script on your web server (for instance, place this code in /var/www/html/mailtest.php
):
<?php
$to = '[email protected]';
$subject = 'Test Subject';
$message = 'Hello!';
$headers = 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
if (mail($to, $subject, $message, $headers)) {
echo "Mail sent successfully";
} else {
echo "Mail failed";
}
?>
Replace [email protected]
with a valid test address and open the script in a browser (e.g., http://your_server/mailtest.php
). Check your mail logs for any errors and confirm the test message appears in your inbox (again, watch for spam/junk folders).
Step 5: Mail Never Received / Spam Issues
In today’s email environment, major providers (Gmail, Outlook, etc.) often block or flag emails as spam unless you set up proper authentication (SPF, DKIM, DMARC) or use a sender with strong IP reputation. Even if your server sends mail, it may not land in the recipient’s inbox.
Recommended steps to improve deliverability:
- Set up SPF, DKIM, and DMARC: Update your DNS records so your domain explicitly authorizes this server to send mail. Check your DNS host’s documentation or a guide on email authentication.
- Use an external SMTP provider: Relaying through a trusted service (e.g., Sendgrid, Mailgun, Gmail) greatly increases the likelihood that your emails will arrive in the inbox rather than being filtered.
For more details on configuring Postfix to relay mail through external SMTP providers, see:
Conclusion
By installing and configuring Postfix (or another MTA) and pointing PHP’s mail()
to /usr/sbin/sendmail
, you can send basic emails from your server. However, for consistent and reliable delivery—especially to major providers—relay your messages through a trusted SMTP service and set up authentication records (SPF, DKIM, DMARC) in your DNS. This ensures your emails have the best chance of reaching the intended inbox.
Let me know if this helped. Follow me on Twitter, Facebook and YouTube, or 🍊 buy me a smoothie.
Postfix installed successfully. But mail not sent to any recipient. Every try it returns with
“Mar 2 14:49:32 ip-172-26-0-195 postfix/smtp[1160171]: 2EE3140328: to=, relay=none, delay=30, delays=0.02/0.01/30/0, dsn=4.4.1, status=deferred (connect to mail.moiboo.com[43.255.154.47]:25: Connection timed out)”
“Mar 2 14:51:34 ip-172-26-0-195 postfix/smtp[1160172]: E41D14031F: to=, relay=none, delay=627, delays=477/0.01/150/0, dsn=4.4.1, status=deferred (connect to alt2.gmail-smtp-in.l.google.com[2a00:1450:4013:c16::1a]:25: Connection timed out)”
I don’t know how to proceed next. can you please help me in this
this solution partially worked
the website said mail was successfully sent
But I got a message bounce back on the email
said: 550 5.7.1
Authentication Required (in reply to end of DATA command)
as I have to authenticate with username / password
before sending emails
how do I authenticate
ubuntu 20.04
php 7.4
Hi,
Excellent tutorial and thank you very much.
I’m hoping you can help with www-data@ when I send with Postfix. This is how it appears now: www-data
I would simply like my email address to show here.
Hey, So I’m seeing some good reviews on this and I would like to try it out. I just have one question (if I may): Why is ‘inet_interfaces’ set to ‘loopback-only’?
It’s for security. We configure Postfix to send and receive emails only from the server on which it is running on—that is, from localhost.
For that to happen, Postfix needs to be configured to listen only on the loopback interface, the virtual network interface that the server uses to communicate internally.
THANK YOU SO MUCH!!!! YOU ARE A GOD SENT PERSON!! i was totally going crazy already its been a week ive been trying to figure this out BUT I just saw this blog post today and omg!!! Thank you!!! You are a life saver! 🙂 But there is one problem, like its not a verified email like google says: “Be careful with this message
Gmail could not verify that it actually came from [email protected]. Avoid clicking links, downloading attachments, or replying with personal information.” If you can help me on how to fix this? Anyways 1000000 times Thank you!!!!!!!!!!!!!!!!
postfix/smtp[21099]: connect to mx01.mail.icloud.com[17.57.154.6]:25: Connection timed out im seeing this in AWS
Ubuntu 16.04 in July 2020:
ignores -y in “sudo apt install -y mailutils” (man apt lacks mention of -y)
the postfix configuration screen fails to appear.
main.cf does not exist in /etc/postfix (instead it’s main.cf.proto)
Same findings after sudo apt-get install mailutils”
Thanks Tom. I’ll need to test this on 16.04 again when I get the chance.
What happens if you run
sudo apt install postfix
Thank you so much! Solved my mail problems 🙂
Hi got this message:
host ASPMX.L.GOOGLE.COM[2a00:1450:400c:c09::1a] said: 550-5.7.1 [2a00:6d40:72:6d28::1] Our system has detected that this message does 550-5.7.1 not meet IPv6 sending guidelines regarding PTR records and 550-5.7.1 authentication. Please review 550-5.7.1 https://support.google.com/mail/?p=IPv6AuthError for more information 550 5.7.1 . o7si15131076wrm.214 – gsmtp (in reply to end of DATA command))
Any idea how to solve this?
Thanks
This worked for me to get my WordPress site to send contact form messages to our e-mail address! Thanks so much for the help!
👍
excellent! Thanks so much, sved me some headaches ..
Klaus
Thanksss 👏👏👏👏👏
Ubuntu Server 18.04, October 2018
“Package ‘mailutils’ has no installation candidate”
Tested and working in 18.04. What happens if you run:
This also works with Ubuntu 18.04
Great Post thanks. Simple and easy to follow.
Thanks for stopping by!
Hey. When are you going to post article for ” How to get PHP mail() working on Ubuntu “18.04”
Thanks, it works for Ubuntu 17.10 and 7.1 too 🙂
Great 🙂
Thank you for this guide. However, I cannot send to Gmail from my DigitalOcean droplet.
It seems Gmail has banned the IP address of your DigitalOcean droplet. That’s unlucky. You could try creating another Droplet to get a new IP or try sending mail through an external SMTP server.
Thanks I got it working but everything goes straight to Gmail spam box. Is there a way around it?
You’ll need to consult your domain host about setting up Domain Keys and SPF records.
Domain Keys is an e-mail authentication system that allows for incoming mail to be checked against the server it was sent from to verify that the mail has not been modified. This ensures that messages are actually coming from the listed sender and allows abusive messages to be tracked with more ease.
SPF will specify which machines are authorized to send email from your domain. This means that only mail sent through this server will appear as valid mail from your domain when the SPF records are checked.
You could also route mail through an external SMTP server or route mail through Gmail’s SMTP server, but you’ll be limited on how many emails you can send per day.
1) postfix configuration did not appear
so what to do ?
2) wish to send emails externally
using ubuntu 17.10 & php7.1
Same issue, postfix is not installed for me on Ubuntu 18.04 LTS.
sudo apt-get install postfix