So you have a staging environment set up, and want to catch all emails that go out? You might use MailTrap for that. It's a great hoste...
So you have a staging
environment set up, and want to catch all emails that go out? You might use MailTrap for that. It's a great hosted solution. But if you have an app that sends a lot of emails, and undergoes a lot of testing... you will soon hit MailTrap's 1000 emails/month limit... and even the 10.000 or 100.000 emails/month limit. What do you then?
Well... what if I told you that you can use MailPit, the same tiny software you might use on localhost
? Yup, you can install it on your staging server, and have a FREE solution to test outgoing emails. I haven't found any tutorial online on how to do this for a default Laravel setup, so here's me giving you step-by-step instructions.
In this tutorial, I'm going to focus on my setup:
Step 1. SSH to your server
ssh [email protected]
Step 2. Download and run the installer:
sudo bash < <(curl -sL https://raw.githubusercontent.com/axllent/mailpit/develop/install.sh)
(it will ask for your sudo password)
Step 3. Run Mailpit as a Background Service
sudo nano /etc/systemd/system/mailpit.service
Then inside the editor:
[Unit]
Description=MailPit Email Catching Service
After=network.target
[Service]
ExecStart=/usr/local/bin/mailpit --listen 127.0.0.1:8025
Restart=always
[Install]
WantedBy=multi-user.target
To save, press Ctrl+O, then Enter. To exit, press Ctrl+X.
Step 4. Start & enable the service
sudo systemctl enable mailpit
sudo systemctl start mailpit
Step 5. Allow external access to port 8025 (web interface) and 1025 (SMTP):
sudo ufw allow 8025
sudo ufw allow 1025
You can then check that the rule works with sudo ufw status
.
Note: We're only doing this to easily test that it's working. We will remove these in the last step of this tutorial.
Step 6. Verify MailPit is running
MailPit should now be running and accessible via the default port 8025 (web interface) and 1025 (SMTP).
Go to your IP, port 8025 and see if it loads (eg. http://167.87.78.123:8025).
Step 7. Verify MailPit receives emails
In your staging environment, change your MAIL configuration to use this Mailpit installation:
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
Send an email, then see it in the web interface.
Note: If you're having problems receiving an email, please run
php artisan cache:clear
. If that still doesn't work, please send an email manually by installing swaks withsudo apt install swaks
, then runningswaks --to [email protected] --server 127.0.0.1:1025
. This will send an email directly from your server to MailPit. If this manual email works, then the problem is misconfiguration in Laravel - fix your env file and cache until it works. A manual deployment usually fixes things, because it clears everything (php artisan optimize:clear
).
Step 8. Add a new DNS record
I use Cloudflare, so I've added an A record that points from mailpit.mydomain.com
to my server's external IP (167.87.78.123
). And yes, I've enabled Cloudflare's SSL.
Step 9. Add a site on Laravel Forge
We could manually set up Nginx, but I think it'll be cleaner to have mailpit show up as an application on Forge. So go to your server and create a new simple app:
You don't need to install anything afterwards (no Git repo, no WP, no phpMyAdmin).
Step 10. Add a new SSL Certificate
Use "Let's Encrypt" in Forge to set up an SSL certificate for that subdomain:
Step 11. Proxy your subdomain to Mailpit
Edit your Nginx configuration:
And within the existing location / {}
, instead of the default, add your proxy:
location / {
# No longer needed:
# try_files $uri $uri/ /index.php?$query_string;
# Proxy requests to MailPit
proxy_pass http://localhost:8025;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Step 12. Add Basic HTTP Authentication
In Forge, go to Security and add a new HTTP Basic authentication:
Now it all works! Now when you go to your subdomain (eg. mailpit.mydomain.com
), you will be asked for username & password:
Then you'll have access to any emails your applications send:
But we're not 100% done yet. One more thing to do:
Step 13. Beef up security - only allow local access
Yes, everything works now! You can go to mailpit.mydomain.com
, authenticate and see your emails... BUT! Your IP is exposed:
http://167.87.78.123:8025/
, they will see all emails too;To restrict access from the public, let's make your Mailtrap instance only receive input from apps on the same server. Let's remove the two rules we added in step 5:
sudo ufw delete allow 8025
sudo ufw delete allow 1025
Now we're really done. Let's test:
http://167.87.78.123:8025/
should no longer work;https://mailpit.mydomain.com
should still work;That's it. Hope you enjoyed this tutorial, and find it useful. Personally, after setting this up, I've never used MailTrap again. Ok fine it happened yesterday, you make a good point. But still!
Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.
What do you think about this?
Wondering what our community has been up to?