Configure email server on a third party host using CPanel, while continuing your app server on your favourite VPS.
Background
Typically I configure email server to be on the same server as my NodeJS / PHP app.
Bad practice? Sure. But, it works just fine for the kind of applications that I write. I can see how horribly this can go wrong though -
- Your app server goes down and you have no way to send communication to your users
- Mail servers simply get more spam, more probes - this keeps the server busy for no reason. This means your main app can suffer
There are simply better ways to design, without breaking the bank or introducing any complexity - we can just shift mail handling to an external party.
What exactly is the architecture?
Quite simple.
- My application on NodeJS continues to reside on VPS (let’s call this “App IP”)
- Mail server is shifted to another server
I could potentially use another VPS box and run Postfix (& associated paraphernalia). If I had been using Virtualmin or any such tools, I could potentially clone the virtual server and make it easier.
However, I am quite frustrated on the issues maintaining Postfix (and friends) by myself. And, I had a few CPanel based cheaper hosting solutions lying around in my inventory. So, I just took the easy way out.
I went ahead and configured CPanel to accept emails for my app.
Why is this a big deal?
There is nothing to this, really. But, it was indeed a learning experience for me - an inexperienced system admin, do-it-all, and mess-it-all guy.
The major issue was with the domain management.
DNS configuration is quite simple for an application with everything on a VPS. I just point the name server to the ones I configured on VPS, or point the A record to the specific VPS IP.
The MX record, which is responsible for receiving mails, just points to fully qualified domain name (FQDN) used by the ‘A’ record pointing to App IP.
For a domain on any of the popular domain service providers, the configuration looks like this -
Host Name | Type | Address/Value |
---|---|---|
domain.com | A | 105.1.1.1 |
domain.com | MX | domain.com |
This will enable mail for @domain.com
addresses, and your application serves HTTP requests on ports designated in the web server on App IP.
If you throw an external web server in the mix, you land in a bit of a pickle for DNS configuration -
- MX cannot point to an IP
- You cannot just create another ‘A’ record pointing to a different IP
** Bad configuration **
Host Name | Type | Address/Value |
---|---|---|
domain.com | A | 105.1.1.1 |
domain.com | A | 75.1.1.1 |
domain.com | MX | domain.com |
‘A’ record will round-robin requests. So your app requests can go to the new ‘Mail IP’ or your mails can ping ‘App IP’ for mail handling.
Solution
There are two parts to the solution.
- Your DNS configuration will have to revert to a recommended practice of using a prefix to the domain
- CPanel on mail server needs to understand that
mail.domain.com
is an alias fordomain.com
email address
First, configure the DNS using tools provided by your domain name service provider.
Host Name | Type | Address/Value |
---|---|---|
domain.com | A | 105.1.1.1 |
mail.domain.com | A | 75.1.1.1 |
domain.com | MX | mail.domain.com |
Next, go to CPanel > Domains > Zone Editor and enable it to manage requests to mail.domain.com
.
Host Name | Type | Address/Value |
---|---|---|
domain.com | MX | mail.domain.com |
mail.domain.com | A | 75.1.1.1 |