![]() |
Setting up a Mail Server with Mailcow and Amazon SES (DigitalOcean Guide) |
Introduction
Hosting your own full-featured email server can give you greater control over your domains and mailboxes. In this guide, we’ll walk through implementing a Mailcow email server on a DigitalOcean Droplet and integrating it with Amazon SES (Simple Email Service) for improved email deliverability. We will cover both incoming and outgoing email handling, discuss whether to use Amazon SES for receiving mail or rely on Mailcow’s built-in stack, and show how to configure SES as an outbound SMTP relay. Additionally, we’ll examine the pros and cons of using SES for sending-only versus for both sending and receiving, outline a recommended architecture for multiple domains (with a web UI to manage users), and provide step-by-step setup instructions. Along the way, we’ll highlight best practices for security (SPF, DKIM, DMARC, PTR records), scalability, and mailbox forwarding to external addresses.
Mail Receiving: Amazon SES vs. Mailcow’s Built-in Stack
Amazon SES can receive emails on your behalf, but it is not a traditional mailbox storage service. SES’s inbound service is designed to accept mail and then perform actions like dropping it into an S3 bucket, triggering a Lambda function, or forwarding to Amazon WorkMail or SNS. It does not directly store mail for IMAP/POP3 access. By contrast, Mailcow provides a complete receiving stack (Postfix + Dovecot) that receives emails and stores them in user mailboxes for IMAP/webmail access.
-
Using Amazon SES for Incoming Mail: While technically possible (you could configure SES to receive mail for your domain and then forward it via AWS Lambda or other means to your Mailcow server or storage), this approach is complex and not natively supported. You would have to maintain custom scripts or AWS services to move the mail from SES to your Mailcow mailboxes. Additionally, SES charges for incoming email after the first 1,000 messages (around $0.10 per 1,000 emails), which can add cost for busy domains. In practice, there is “no real reason to use SES for incoming emails” when running your own mail server. SES’s benefits (spam/virus filtering and high availability) are largely replicated by Mailcow’s components (Rspamd spam filter, ClamAV antivirus, etc.) and by the fact that you control the server environment.
-
Using Mailcow’s Own Receiving: It’s generally better to use Mailcow’s built-in SMTP receiving for incoming mail. Mailcow will listen on standard mail ports (TCP 25 for SMTP) and accept mail for your domains, delivering it to local mailboxes. This way, incoming mail is immediately stored on your server and accessible via IMAP and webmail (SOGo web interface included in Mailcow). There is no additional cost per message, and you avoid the complexity of routing through AWS. The only prerequisite is that your Droplet’s network allows inbound SMTP on port 25 (DigitalOcean may block SMTP by default for new accounts to combat spam, so you might need to request unblocking of port 25).
Conclusion: For a Mailcow setup, use Mailcow for receiving mail directly. Amazon SES is not designed to be an IMAP/Inbox solution; it’s best used for sending. Focus SES integration on outbound delivery, while pointing your domains’ MX records to your Mailcow server to handle inbound mail storage.
Using Amazon SES as an Outbound SMTP Relay
One of the key integrations in this hybrid setup is using Amazon SES to send outgoing mail from your Mailcow server. Amazon SES can act as a smart host (relay) for your outgoing SMTP traffic. This means Mailcow’s Postfix will hand off outbound emails to Amazon’s SMTP servers, which then deliver the messages to recipients on the internet. The advantages of this approach include improved deliverability (SES’s IPs have established reputation), compliance with DigitalOcean’s policies (since DO blocks direct SMTP, relaying via SES on an alternate port can circumvent that once SES is reachable), and avoiding having to manage your own SMTP reputation and reverse DNS in depth.
Can Amazon SES be used as the outbound SMTP relay? – Yes. Amazon SES provides SMTP endpoints you can connect to, after verifying your domain and credentials. In this setup, Mailcow treats SES as an external SMTP relay. The Mailcow team itself notes that SES “integrates just fine as [a] relayhost” and many self-hosters use SES for sending to ensure their mail isn’t rejected. In fact, AWS even provides guidance on integrating Postfix with SES, and Mailcow has a convenient UI to configure relay hosts.
Configuring Mailcow to Relay via SES
Mailcow (which is a Dockerized stack) allows setting up sender-dependent transports through its admin UI. Here’s how to configure SES as the relay:
-
Verify your Domain in Amazon SES: In the AWS console for SES, add each domain you intend to send from. Verify the domain ownership (via DNS record) and request production access (to lift sandbox restrictions). Enable “Easy DKIM” for the domain in SES so Amazon can sign outgoing mail with DKIM (you’ll add 3 CNAME records for DKIM). This ensures your domain is authorized to send through SES. Also, obtain your SMTP credentials (an SMTP username and password generated by SES) – these are separate from your AWS console login, created in the SES console.
-
Add SES as a Relay in Mailcow: Log into Mailcow’s admin UI on your Droplet. Go to Configuration and Details → Routing → Add sender-dependent transport. Here, add the SES SMTP host details:
-
Host: The SES SMTP endpoint for your region, e.g.
email-smtp.us-east-1.amazonaws.com
. (Use the region that matches where you verified the domain.) -
Port: Typically 587 (submission port with STARTTLS) or 465 (SMTPS). SES supports 587 with STARTTLS. Mailcow will attempt TLS by default; ensure port 587 is specified if needed.
-
Username: The SMTP username from SES (looks like an IAM access key).
-
Password: The SMTP password from SES (looks like a secret key). Note: This will be stored in Mailcow config (in plain text), which is normal but be sure to keep your Mailcow updated and secure.
-
(Mailcow’s UI might have a “Use TLS” toggle or it will automatically use TLS if the port is 587 with STARTTLS. Under the hood, Postfix is configured to use TLS for relay, which SES requires.)
Save the new relay transport. You can use the Test button in the relay list to verify connectivity – enter a from-address (your verified domain) and run the test. A successful result should show a
250 Ok
response from SES. -
-
Assign the Relay to Your Domain(s): Defining the relay alone isn’t enough; you must tell Mailcow which domains should use it. Go to Mail Setup → Domains in the UI, edit each domain that will send via SES, and select the newly added SES relay in the “Sender-dependent transports” dropdown. Save the domain settings. This associates your domain with the SES relay for all outgoing mail. (If you skip this, Mailcow will continue sending out directly, as one user discovered before selecting the external SMTP host in the domain config.)
-
Restart Postfix (if needed): Mailcow’s UI changes should apply the config. To be sure, you can restart the Mailcow stack or at least the
postfix
container. After that, any new outgoing email from that domain will be handed off to SES. Check Mailcow’s log (/var/log/mail.log
or the UI’s log viewer) – you should see Postfix delivering toemail-smtp...amazonaws.com
instead of directly to the recipient domain.
At this point, your Mailcow server still receives mail directly, but sends mail via Amazon SES. This hybrid approach is commonly used when direct SMTP from the server is problematic (due to ISP blocks or IP reputation). In our case on DigitalOcean, it helps avoid blocked ports and improves deliverability.
Pros and Cons of Using Amazon SES (Sending-Only vs. Sending+Receiving)
Using Amazon SES for sending only, versus for both sending and receiving, has different implications. Below is a comparison to help decide the architecture:
-
SES for Outbound Only (Mailcow handles Inbound):
-
Pros: You get SES’s high deliverability (AWS manages IP reputation, feedback loops, etc.). Outgoing mail is less likely to be flagged as spam due to known-good sending IPs. You avoid dealing with reverse DNS (PTR) for your IP’s reputation (though you should still set one). Also, you retain full control of incoming mail on your server, with no extra cost for incoming messages (Mailcow can receive unlimited mail for free). This setup is simpler; no complex pipelines for inbound mail.
-
Cons: Slight additional cost for outbound emails via SES (after the free quota on AWS – typically $0.10 per thousand emails sent). Outbound mail flow depends on a third-party (if AWS has an outage in SES, sending could be delayed). Also, using SES means trusting AWS with outbound email content (a potential privacy consideration). That said, content is transmitted over TLS to SES, and many are comfortable with AWS’s policies.
-
-
SES for Both Sending and Receiving (Full SES Integration):
-
Pros: Amazon handles both inbound and outbound infrastructure – incoming mail is filtered for spam/viruses by SES and you don’t need to expose your droplet’s SMTP port to the world. It could potentially improve reliability of inbound (AWS’s servers are highly available). Bounce processing for incoming (if an email to you bounces back to sender) is also handled by AWS.
-
Cons: This approach is not recommended for a mailbox server setup. SES has no native mailbox storage – you’d have to forward incoming mail from SES to Mailcow or store it in S3 and retrieve it, which is complex. Essentially, you’d be paying AWS to “catch” your mail only to send it to your Mailcow anyway. This adds latency and multiple points of failure. Cost can ramp up: after 1,000 free incoming emails, Amazon charges per message, which “sounds expensive” for high volumes. Additionally, forwarding from SES to Mailcow isn’t straightforward – SES cannot directly relay to an arbitrary SMTP server without custom solutions. Most community feedback agrees there is “no real reason to use SES for incoming” in a self-hosted scenario, except perhaps in edge cases like dynamic IPs with no other solution. You’d be better off using a small SMTP relay or dynamic DNS for inbound if needed, rather than SES.
-
Summary: The recommended approach is to use Amazon SES for outbound only. Let Mailcow handle incoming mail on the droplet. This gives you the best of both worlds: reliable delivery for outgoing mail and full control (with no extra fees) for incoming mail storage. Using SES for both directions provides marginal benefits at a significantly higher complexity and cost.
Recommended Architecture for Multi-Domain Mail Server
To support multiple domains and mailboxes with a user-friendly admin interface, Mailcow is an excellent choice. It supports hosting many domains on a single server and provides a web UI to add/remove domains, mailboxes, aliases, and more. The high-level architecture will look like this:
Figure: Hybrid Email Architecture – A self-hosted mail server (Mailcow on a DO Droplet) handles IMAP, webmail, and inbound SMTP for multiple domains, while Amazon SES is used as an outbound SMTP relay to improve deliverability. DNS (MX, SPF, DKIM, etc.) and other AWS services like Route53 or S3 (for backups) integrate into the setup as needed.
In this architecture, you deploy a single mail server (Mailcow) on your Droplet. You choose one primary hostname for this server (e.g. mail.yourprimarydomain.com
) which will be used for the server’s SSL certificate and PTR record. All your email domains (e.g. yourprimarydomain.com, second-domain.com, third-domain.org) will point their MX records to this mail server hostname. For example, in each domain’s DNS zone you might set:
-
MX 10 mail.yourprimarydomain.com.
(meaning mail for that domain is handled by your Mailcow server).
Mailcow’s UI lets you add each domain (Mail Setup → Domains → “Add Domain”) and then create mailboxes under those domains. There is a unified interface to manage all domains and users. Users can log in to webmail (SOGo) with their email address and password, regardless of which domain.
Managing Multiple Domains: You will need to verify each domain in Amazon SES as well, because SES will only send emails if the “From” domain is verified. That means for every domain you add to Mailcow for sending, you should perform the SES verification (and DKIM setup) in the AWS console. Once verified, in Mailcow’s domain settings you can enable the SES relay as we did earlier. Mailcow supports setting the same relay for multiple domains – just select the SES transport in each domain’s settings. This setup scales to many domains easily. The only limitation is that all outgoing mail goes through SES, which is fine as long as those domains are verified under your SES account (you might use one AWS account for all, or multiple if separating clients – SES allows thousands of verified identities).
Reverse DNS (PTR) for Multiple Domains: Since all mail is actually sent by Amazon SES, you technically rely on Amazon’s PTR records (which AWS manages for their IPs). However, it’s still good practice to set a PTR for your Droplet’s IP pointing to your mail server hostname (for completeness and in case your server ever sends some direct mail, like bounce notifications). On DigitalOcean, you can configure PTR in the networking settings by assigning your droplet a name. Use the primary hostname (e.g. mail.yourprimarydomain.com
) for PTR. All sending domains can share this single PTR without issues – PTR does not need to contain every domain, just the mail server host. Ensure the forward DNS for that hostname matches the droplet’s IP as well.
Web UI for Users: Mailcow provides a web interface (SOGo groupware) for users to read/send mail, as well as an admin UI for you. The admin UI is where you add/remove users or domains. You can even delegate domain administration to others if needed. This covers the “multiple domains and mailboxes with a UI” requirement out-of-the-box. No additional software is needed for user management.
Scalability: For a typical small to medium organization, a single Droplet (with sufficient RAM and CPU) can handle a decent number of domains and mailboxes – especially since heavy lifting for outbound is offloaded to SES. If your needs grow, you can scale vertically (increase Droplet size for more CPU/RAM, and attach larger storage for mailboxes). Mailcow can also be backed up/restored easily (all configs and mail stored in volumes or dumps). The AWS architecture example above even shows using S3 for backups. While Mailcow isn’t designed to be clustered across multiple machines for active load-balancing, you can scale by splitting roles (for example, host the database or Redis externally if needed, or use SES/WorkMail for some users). Generally, one Mailcow instance should suffice for hundreds of users; monitor resource usage (Rspamd and ClamAV can be memory-intensive if under heavy spam load). Using SES helps scalability since Amazon handles the outbound throughput (you just have SES sending limits to mind, which you can increase by request if needed).
Implementation Guide: Mailcow + SES Hybrid Setup
In this section, we’ll provide a concise step-by-step guide to implement the Mailcow + Amazon SES setup, along with links to relevant documentation for further details:
-
Set Up the DigitalOcean Droplet and Mailcow: Start by creating a new Droplet (Ubuntu is a good choice) on DigitalOcean. Ensure you have ports 25 (SMTP), 587 (submission), 993/143 (IMAP), 80/443 (HTTP/HTTPS) available (DO may require a support ticket to unblock SMTP). Follow the Mailcow installation instructions from the official docs (Mailcow is typically installed via Docker Compose). Use a fully-qualified domain name (FQDN) for the mail server host (e.g.
mail.example.com
) and make sure DNS A/AAAA records point to your droplet. Once Mailcow is up, access the web admin and set a strong admin password. -
Configure DNS Records for Mailcow: For each domain you plan to use:
-
MX Record: Point it to your mail server’s hostname (e.g.,
example.com MX 10 mail.example.com
). This directs incoming mail to your server. -
A Record (for the mail host): Ensure
mail.example.com
(or your chosen hostname) points to the Droplet’s IP. -
Autodiscover/Autoconfig (optional): Mailcow can serve autoconfig; you might add DNS records as per Mailcow docs if you want email clients to auto-configure (this is optional, not critical).
-
Reverse DNS: Set your Droplet’s PTR to
mail.example.com
via DO’s networking settings (improves credibility of your server IP).
-
-
Set Up Amazon SES (AWS side): In AWS, verify each domain in Amazon SES:
-
Go to SES > Verified identities and add your domain (e.g., example.com). SES will provide a TXT record to add to DNS for verification.
-
Enable DKIM signing for the domain in SES (usually called “Easy DKIM”). SES will give you 3 CNAME records (with names like
*_domainkey.example.com
) – add these to your DNS. Once verified, SES will automatically DKIM-sign outgoing mail from that domain. -
(Optional) Configure a custom MAIL FROM domain in SES for DMARC alignment. For example, you might use
bounce.example.com
as a MAIL FROM. SES will require a verification (MX record pointingbounce.example.com
tofeedback-smtp.REGION.amazonses.com
and an SPF include). This step ensures the envelope sender for emails is a subdomain of your domain, which can align SPF with your domain’s DMARC (if you skip this, SES will use an amazonses.com address as the MAIL FROM – which is okay since SPF will pass for amazonses.com, but it won’t align with your domain unless DKIM passes). In practice, as long as DKIM is set up, your DMARC should pass (because DKIM will align with your domain), so custom MAIL FROM is a nice-to-have for completeness. -
Move your SES out of the Sandbox: New SES accounts are in “sandbox” mode, allowing only sending to verified addresses. Submit an SES Sending Limits request to AWS support to get out of sandbox and raise sending limits as needed.
-
-
Obtain SMTP Credentials from SES: In Amazon SES console, create SMTP credentials (this is often under SMTP Settings – you generate a username/password). Save these, as you will plug them into Mailcow.
-
Configure Mailcow to Use SES for Outgoing: As detailed in the earlier section, log into Mailcow admin and go to Configuration → Routing:
-
Add a new relay (sender-dependent transport) for SES with host
email-smtp.<region>.amazonaws.com
and port 587, and the SMTP user/pass from SES. Save it. -
Test the relay from the UI to confirm Mailcow can connect/authenticate.
-
Now go to Mail Setup → Domains, edit each domain (example.com, etc.) and assign this SES relay in the “Transport” field. Save changes.
-
-
Set Up SPF, DKIM, DMARC for Each Domain:
-
SPF: Update the domain’s TXT record for SPF to include both your mail server and Amazon SES. For example, if you were previously using just your own server you might have
v=spf1 a:mail.example.com -all
. Now, since SES will be sending, include SES’s SPF designation. AWS’s documentation says that if you use a custom MAIL FROM, publish SPF for that subdomain. The simpler method (if not using custom MAIL FROM) is to include SES’s sending domains. A typical SPF that covers both could look like:
v=spf1 include:amazonses.com include:_spf.yourdomain.com ~all
Hereinclude:amazonses.com
authorizes Amazon SES to send for you. Alternatively, Amazon provides region-specific SPF includes (check SES docs for the exact include domain if needed). Also include any other sending sources you use.
Ensure SPF ends with~all
or-all
as per your preference (softfail vs fail). You can use tools like port25 verifier to test SPF/DKIM/DMARC. -
DKIM: If you enabled Easy DKIM in SES, AWS will sign outgoing mails with its keys (once DNS CNAMEs are verified). You do not necessarily need Mailcow’s own DKIM for those domains. In fact, having Mailcow also sign might cause duplicate DKIM headers. By default, Mailcow generates a DKIM key for each domain – you can publish it (as a DNS TXT record for selector
dkim._domainkey
). However, when relaying through SES, you might choose to rely on SES’s DKIM signature instead. If you do keep Mailcow’s DKIM active, make sure to adjust its signing settings to avoid conflicts. For example, AWS recommends not signing theDate
andMessage-ID
headers when you do your own DKIM, because SES will add or adjust those, causing Mailcow’s DKIM signature to fail. One Mailcow user reported that removingdate
andmessage-id
from the signed headers in Rspamd fixed a DKIM fail when using SES. Alternatively, you can disable Mailcow’s DKIM for that domain by not publishing Mailcow’s DKIM DNS record (so only the SES DKIM is detected by recipients). As long as at least one DKIM signature (SES’s) passes and aligns with your domain, DMARC will be satisfied. -
DMARC: Publish a DMARC record for your domain to monitor and enforce policy. Start with a policy of
none
(just monitoring) and an aggregate report address. For example:
_dmarc.example.com TXT "v=DMARC1; p=none; rua=mailto:postmaster@example.com; sp=none; aspf=r;"
This will request reports to be sent to your email and not yet enforce any rejection. Once you confirm SPF/DKIM are passing, you can changep=quarantine
orp=reject
as needed to enforce protection. Ensureaspf=r
(relaxed SPF alignment) unless you set up the custom MAIL FROM, because relaxed alignment will treat subdomain matches as okay (which helps if SES uses bounce.subdomain). -
PTR: As mentioned, set the PTR for your Droplet’s IP to your mail server hostname (done in DO control panel). This isn’t directly used by DMARC, but many mail systems check that an SMTP sender has a valid reverse DNS. Even though SES is doing the sending, having proper PTR on your server is still a good practice and is essential if any mail ever goes out from your IP.
-
-
Testing the Setup: Send test emails from a mailbox on your Mailcow (you can use the SOGo webmail or an email client via SMTP on Mailcow which will then relay). Test sending to an external address (like a Gmail account) and verify:
-
The email is received, and the headers show it was relayed via Amazon SES (you might see an
amazonses.com
Received header or that the sending IP is an Amazon AWS IP). -
Check that SPF shows pass (it should reference amazonses.com in the Received-SPF header and show pass), DKIM shows pass (for your domain’s DKIM, likely the SES signature), and DMARC shows pass or at least doesn’t fail. You can send an email to a service like check-auth@verifier.port25.com which will reply with a report on SPF/DKIM/DMARC alignment.
-
Test incoming mail by sending from an external account to your Mailcow mailbox. Ensure it arrives in the inbox (Mailcow logs will show the incoming SMTP connection). If there are issues receiving, double-check your MX record and port 25 access.
-
-
Monitor and Tune: Once running, keep an eye on your AWS SES dashboard (it will show send statistics, bounce rates, etc.). SES will handle bounce notifications automatically – hard bounces and complaints will reflect in your SES console. You may integrate AWS SNS to get alerts on bounces if you do large mailings, but for typical use this isn’t required. On the Mailcow side, monitor the queue to ensure mails are flowing out via SES. If something isn’t sending, check
/var/log/mail.log
(ordocker-compose logs postfix
) for errors – a common issue could be SES credentials or domain not verified.
For more detailed documentation, you can refer to Mailcow’s official docs on Relayhosts and AWS’s official docs on Integrating Amazon SES with Postfix (which underpins what Mailcow is doing under the hood). The Mailcow community forum and Wiki are also great resources if you run into specific issues (for example, handling DKIM when relaying or troubleshooting why incoming mail might not be received).
Security and Email Authentication Best Practices
Implementing strong security and authentication for your mail server is crucial:
-
SPF (Sender Policy Framework): Ensure each of your domains has an SPF DNS record that authorizes both your Mailcow server (if it ever sends directly) and Amazon SES. Typically, include Amazon SES’s domain or mechanisms. AWS SES by default passes SPF by using its own MAIL FROM domain (amazonses.com), but you still want your domain’s SPF to list SES as an allowed sender so that receiving servers see that you intended SES to send mail for you. Not having SES in SPF could lead to “spf=neutral” results. As shown earlier, use
include:amazonses.com
or the region-specific include. Keep only one SPF record per domain (consolidate all includes into one record string). -
DKIM: With SES handling DKIM, make sure you’ve added the CNAME records AWS provided and that the status in SES shows as verified for DKIM. You can optionally disable Mailcow’s own DKIM to avoid confusion. The goal is that every outbound email gets a DKIM signature by SES (with
d=yourdomain.com
). If you have to use Mailcow’s DKIM (say, if you want to double sign), ensure it’s correctly set up and doesn’t sign headers that SES will alter. You may prefer to let SES handle DKIM entirely, as it simplifies things and AWS rotates the DKIM keys for you if needed. -
DMARC: Use DMARC to enforce your policies. After testing in monitoring mode, set a policy to quarantine or reject unauthorized mail. This helps protect your domains from spoofing. For example:
v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; fo=1; aspf=r; adkim=r
. Theadkim=r; aspf=r;
means relaxed alignment (which is fine given SES’s use of subdomains). You could tighten to strict (s
) if you have custom MAIL FROM matching exactly and are sure all mail will align. Monitor the aggregate reports you get to see if any sources fail DMARC – this could indicate someone spoofing your domain or some service not authorized in SPF. -
TLS Encryption: Mailcow by default will provide a Let's Encrypt SSL certificate for your mail server hostname (for use in HTTPS, IMAPS, SMTPS). Ensure your users always use secure connections (IMAPS on 993, SMTPS on 465 or submission with STARTTLS on 587). In Mailcow’s admin, you can enforce TLS for inbound/outbound. Postfix is configured to use TLS for outgoing to SES (as we set
smtp_use_tls = yes
), and SES requires it, so outbound is encrypted in transit. Also consider enabling HSTS/MTA-STS policies for your domain’s SMTP if desired (advanced, ensures other mail servers know to always use TLS to deliver to you). -
Server Security: Keep the Droplet secure by enabling the firewall (ufw or DO cloud firewall) allowing only necessary ports (25, 465, 587, 993, 443, etc.). Ensure your Mailcow is updated to latest version for security patches (Mailcow has an update script for its Docker images). Use strong passwords for all mailboxes and encourage users to enable two-factor authentication if using SOGo (Mailcow supports 2FA for the admin interface).
-
PTR Record: We have set this but to reiterate – a matching PTR (reverse DNS) for your sending hostname can reduce the chance of your mail being flagged. Some receivers do reject mail if no PTR or if PTR doesn’t match. So if your droplet IP is 203.0.113.5 and your mail host is mail.example.com, ensure the PTR for 5.113.0.203.in-addr.arpa is “mail.example.com.” and that forward DNS for mail.example.com is 203.0.113.5. This symmetry is important for trust.
By following these practices (SPF, DKIM, DMARC, TLS, PTR), you establish a strong email authentication framework. In our hybrid setup, Amazon SES also assists: it handles bounce notifications and complaints. (For example, SES will automatically add problematic recipients to a suppression list if they repeatedly bounce, which helps keep your sending reputation clean.)
Mail Forwarding and Additional Considerations
Mail forwarding (where an email to one of your domains is automatically forwarded to an external address) is a common requirement (for example, you might forward info@yourdomain.com
to a personal Gmail account). With Mailcow, you can set up forwarding addresses or aliases in the UI. However, keep the following in mind:
-
Forwarding and SPF/SRS: When your Mailcow forwards an email from an external sender to another external destination, it’s essentially acting as an intermediate. By default, this can break SPF – the forwarded mail might arrive at Gmail/Outlook from your server (or SES) but with the original sender’s domain in the headers, causing SPF checks to fail. To mitigate this, implement SRS (Sender Rewriting Scheme) for forwarded mails. SRS will rewrite the envelope sender address on forwarded mail to your domain, so that SPF checks at the final recipient use your domain (which is authorized) instead of the original sender’s. Unfortunately, Postfix doesn’t natively support SRS; you’d need a tool like
postsrsd
. As of the last update, Mailcow doesn’t include SRS by default (there were community discussions around it). If forwarding is minimal, you might accept the risk of some forwarded mails failing SPF (in practice, DKIM might carry them through if the original sender had DKIM). But if you rely on forwarding, consider adding postsrsd to your Mailcow setup (some users have documented hacks to integrate it). -
Relay and Forwarding: Note that in older versions, forwarded mails might bypass the relay host and go out directly. Ensure to test that scenario. Mailcow’s newer versions may handle this better, but if not, you might need a workaround to force forwarded mail through SES as well. One way is to treat forwarding as sending (possibly by using Sieve with an explicit SMTP send). Keep an eye on Mailcow’s release notes or community forum if this affects you.
-
Mailbox Quotas and Scaling: Set appropriate mailbox quotas in Mailcow to manage disk usage. If you anticipate heavy use, mount an additional volume to
/var/mail
(or wherever Mailcow stores mail data) for more space. Regularly back up your Mailcow (Mailcow provides scripts to dump data, and you can copy to an S3 bucket or DO Spaces for offsite backup). -
Monitoring: Use Mailcow’s dashboard and logs to monitor mail queue and deliverability. Amazon SES console provides sending statistics and can even send CloudWatch alarms on bounce rates or if you approach sending limits.
By carefully setting up and maintaining these aspects, you’ll have a robust email system: multi-domain capable, with a nice UI for management, and enhanced deliverability through Amazon SES. This hybrid approach is used by many self-hosters to combine the “full ownership” of self-hosted email with the scalability and deliverability of a cloud email service.
Conclusion
In summary, the best practice for a Mailcow on DigitalOcean integrated with Amazon SES is to use Mailcow for what it does best (mailbox hosting, IMAP, webmail, incoming mail processing) and offload the outbound sending to Amazon SES for reliability. Amazon SES should be configured as a relay (via Mailcow’s sender-dependent transports) for all your domains’ outgoing mail. Incoming mail can be received directly by Mailcow to avoid unnecessary complexity and cost. This setup supports multiple domains and mailboxes, all manageable through Mailcow’s web UI, and ensures outbound emails have proper SPF, DKIM, and DMARC alignment for high deliverability.
By following the steps and recommendations above – verifying domains with SES, configuring the relay in Mailcow, setting up DNS records (MX, SPF, DKIM, DMARC, PTR), and addressing security and forwarding considerations – you will have a powerful, full-featured email server. You’ll enjoy the control of self-hosting (no more scattered mailboxes when switching providers) with the sending reputation of Amazon’s infrastructure. For further reading or troubleshooting, refer to Mailcow’s documentation and community forum, as well as AWS’s SES Developer Guide for mail server integration. Good luck with your Mailcow + SES deployment, and enjoy the benefits of a hybrid email architecture!
Sources: Mailcow Documentation and Community Guides, AWS SES Developer Guide, Reddit self-hosting discussions, AWS Open-Source Blog, and Mailcow user experiences on DKIM/DMARC with SES.
Comments
Post a Comment