RunCloud has provisioned your server for a web application and set it up, but how about email? It is not necessary to provision your server in order to send email. But what if you want to send email from your server? We actually recommend using MailGun, SES or Mandrill for transactional email rather than sending it from your own server. We admit it, we are using MailGun and we are really happy with their service.
If you want to send email from your server, please use SwiftMailer or PHPMailer instead of using the direct php mail function. But here, we are just doing testing and we will be sending email from the server.
Please make sure you are login as root inside your server.
To install the necessary tools, enter this command:
apt-get update && apt-get install mailutils
Correcting the sendmail_path inside php.ini
If you want to send an email from PHP7.1, edit the /etc/php71rc/php.ini and search for sendmail_path =. It should be like this:
; For Win32 only. ; http://php.net/sendmail-from ;sendmail_from = firstname.lastname@example.org ; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). ; http://php.net/sendmail-path ;sendmail_path = ; Force the addition of the specified parameters to be passed as extra parameters ; to the sendmail binary. These parameters will always replace the value of ; the 5th parameter to mail(). ;mail.force_extra_parameters = ; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename mail.add_x_header = On
Uncomment the sendmail_path and add the sendmail path. You should have something like this:
; For Win32 only. ; http://php.net/sendmail-from ;sendmail_from = email@example.com ; For Unix only. You may supply arguments as well (default: "sendmail -t -i"). ; http://php.net/sendmail-path sendmail_path = /usr/sbin/sendmail -t -i ; Force the addition of the specified parameters to be passed as extra parameters ; to the sendmail binary. These parameters will always replace the value of ; the 5th parameter to mail(). ;mail.force_extra_parameters = ; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename mail.add_x_header = On
Now restart the php71 with:
systemctl restart php71rc-fpm
If you want other php version to send email too, you can edit their php.ini file:
/etc/php55rc/php.ini # PHP5.5 systemctl restart php55rc-fpm /etc/php56rc/php.ini # PHP5.6 systemctl restart php56rc-fpm /etc/php70rc/php.ini # PHP7.0 systemctl restart php70rc-fpm /etc/php71rc/php.ini # PHP7.1 systemctl restart php71rc-fpm
Now edit your server hostname. You can find it inside /etc/hosts:
127.0.0.1 localhost.localdomain localhost
Change it to your domain:
127.0.0.1 test.runcloud.me test
And then we change the hostname on the fly with:
Now we run:
And answer all the question with Y.
The Basic of PHP Mail function
mail($to, $subject, $message, $headers)
That is the basic way to start sending your email from your server. Now we will do it more like real world usage, but please use SwiftMailer or PHPMailer later.
<?php $to = 'firstname.lastname@example.org'; $subject = 'This is a test email'; $message = 'Hello john!'; $from = 'email@example.com'; $headers = sprintf("From: %s\r\nReply-To: %s", $from, $from); mail($to, $subject, $message, $headers);
Now create the mail.php inside your web application. Make sure you have replaced the $from variable to your own domain name.
Now open your browser and hit the mail.php inside your web app. Wait for a minute……… and crap!!!! The email is not there.
Testing your email with mail-tester.com
Mail Tester is a service to test your email whether you can send the email or not. Now open up Mail Tester website and you should get an email to send to. Add this email to your $to variable and you should get something like this:
<?php $to = 'firstname.lastname@example.org'; $subject = 'This is a test email'; $message = 'Hello john!'; $from = 'email@example.com'; $headers = sprintf("From: %s\r\nReply-To: %s", $from, $from); mail($to, $subject, $message, $headers);
Now hit the mail.php again inside your browser and check the score from Mail Tester. This is my result.
With this score, your email will never reach any inbox. Phewww.
Sender Policy Framework (SPF) is the TXT based DNS record that you can add to your DNS as a policy to for sending email. Your server hostname need to be verified as an email sender.
You can use SPF Wizard to generate your SPF record. This is the records that I am using for my domain (runcloud.me)
runcloud.me. IN TXT "v=spf1 a:test.runcloud.me -all"
test.runcloud.me. IN TXT "v=spf1 ip4:184.108.40.206 -all"
Don’t forget to change your a:<your own domain> and ip4:<your server IP>
This is how it looks like from Cloudflare.
Based on the config, we set our A record(test.runcloud.me) can send email on behalf of runcloud.me. So you can send email using any user. For example, firstname.lastname@example.org.
For the second record, we said that our server IP Address can send email on behalf of test.runcloud.me.
Now we send the email again to Mail Tester and then check the score.
Alright.. now we are getting somewhere.
The Mail Tester will check for MX records. And the domain (runcloud.me) does not have any MX record. Because of there is no MX record, the score will be minus 3. Now I will add bogus MX record. You should use the real MX record for your domain. The bogus MX is just for the sake of testing.
Now I will check the score again after adding my MX record.
Wait!!! I should get 9? Why did I only get 8 marks? Well, that is because I modify the TXT record for the SPF and set it to automatic TTL from CloudFlare. Now I just need to wait to 12 hours. Naah.. Not gonna do that. Let just assume that I already got 9 marks.
Your server reverse IP lookup should return your server hostname (test.runcloud.me). You can do this from Digital Ocean or Linode panel if you are using their service. Or any IaaS based company that provides VPS/Server will always give you access to modify your PTR record.
DomainKeys Identified Mail (DKIM) as it name said, is a domain key. This is also a verification for receiving email. I won’t do DKIM part since it is painful and the score is only 1 mark. But if you really want to send email from your server, you should install it and add it to your DNS.
Domain-based Message Authentication, Reporting & Conformance (DMARC) is also a policy to state that this domain (runcloud.me) is protected by SPF and/or DKIM. I won’t do this too and you should Google on how to do it. And DMARC is still not widely used. But it is good to have it.
Your email should be sending email using SSL/TLS. Fail to do so will resulting in Gmail to block your email as you can see the in the Google Support. You can always monitor your sending email by issuing:
tail -f /var/log/mail.log
This command will monitor sending and response log.
Although I have got the 8 marks from Mail Tester, but Google will still reject my email. Is it worth it to send email from your server? For me, I’m just doing this for fun, but I will never sending email from my own server. Just leave it to the expert, MailGun, Mandrill, SES, etc. If your web application only support PHP Mail function, it sucks. Period!
Categories: Server Management, Tips & Tricks, Tutorials
5 thoughts on “How to Send Email from PHP (With Guided Walkthrough)”
This guide doesn’t work.
Any idea how MailGun compares with SES. What are the reasons for you using MailGun compared to SES?
The guide is not validated by runcloud team. Port 25 is blocked by default. I’m bit dissapointed as i thought runcloud powered up developer without having to put effort too much on server administration but things like simple sendmail is not supported out of the box
Hi Victor, this was 2017 article. RunCloud now supports sendmail (but still not recommended) out-of-the-box. Please contact your host if Port 25 is blocked.
Any newer version of guide for how to set up email sending on RunCloud?