Almost every server ends up needing to send email. Password resets, order confirmations, a cron job that shouts when a backup fails. And almost every time, somebody reaches for the wrong solution — either they install a full mail server to send twelve messages a day, or they point the application at port 25 on localhost and wonder why Gmail silently discards everything.

Read this before you start. Sending email and running a mail server are two different jobs. Sending is a solved problem: you relay through a provider, add three DNS records, and it works — an afternoon, then essentially no maintenance. Receiving is an ongoing commitment involving spam filtering, storage, backups, TLS renewal and reputation management, and the mail you send from a fresh IP address will be treated as suspicious for months regardless of how correctly you configure it.

Part 1 below is the job you almost certainly want. Part 2 is an honest account of the other one, so you can decide with your eyes open.

Part 1: sending application email properly

The shape of the solution: your application hands the message to a local agent, the local agent hands it to a relay provider over an authenticated connection, the provider delivers it. You never talk to the recipient’s mail server yourself, so you never have to build a delivery reputation. What that arrangement costs you is control of the addresses your mail is judged on — the relay replaces the envelope sender, the sending IP and possibly the signing domain, and The Life of an Outbound Email follows a message through all nine stages of that. Come back to it the first time something you sent does not arrive.

Step 1: pick a relay

A relay — also called a smarthost — accepts your authenticated message and delivers it on your behalf. Any transactional email provider does this, and most have a free tier that covers a small site comfortably. What you are looking for is SMTP credentials (a host, a port, a username and a password or API key) and the ability to verify your sending domain.

Your own existing mailbox provider will often work too, if you already pay for hosted email on the domain. That is the cheapest path for low volume: no new account, and the domain is already verified.

Verify: you have a hostname, a port (587 or 465), a username and a password written down, and the provider’s dashboard shows your domain as verified or pending verification.

Step 2: the three DNS records

These three let a receiver attribute your mail to you, which is a precondition for arriving rather than a guarantee of it. They are all TXT records on your domain, and every relay provider gives you the exact values to paste — do not invent them.

RecordWhat it assertsWho sets the value
SPFThese servers are allowed to use my domain in the SMTP envelope. It says nothing at all about the From: header your recipient readsYou, listing your relay’s include
DKIMThis message was signed by whoever holds the private key for the d= domain in the signature — which is your relay, and the d= value is theirs to chooseYour relay generates and holds the key; you publish the public half
DMARCThe only one that mentions the From: header: it asks whether either of the other two authenticated the same organisation, and says what to do when neither didYou choose the policy, and the reporting address

A minimal working set looks like this. The SPF include comes from your provider’s documentation; the DKIM record is generated for you and pasted verbatim.

; SPF - one TXT record on the domain itself, and only one
example.com.  TXT  "v=spf1 include:relay.example.net -all"

; DKIM - selector name comes from your provider
sel1._domainkey.example.com.  TXT  "v=DKIM1; k=rsa; p=MIGfMA0GCSq..."

; DMARC - start permissive, tighten later
_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:dmarc@example.com"

Three things people get wrong here. You may only have one SPF record per domain — if you already have one, merge the new include into it rather than adding a second, because two SPF records is a permanent error, not a merge. Merging has a cost worth knowing about, though: an SPF evaluation is capped at ten DNS-querying terms, and a single include: pointing at a relay routinely spends three of them, two of which are inside a record you do not own and cannot see change. And start DMARC at p=none, which asks receivers to report but not to act. Read the reports for a couple of weeks, confirm nothing legitimate is failing, then move to p=quarantine and eventually p=reject.

Verify: dig +short TXT example.com shows exactly one v=spf1 string, and dig +short TXT _dmarc.example.com returns your policy. DNS changes are not instant — allow for the TTL on the old records.

Step 3: a local relay agent

You could put SMTP credentials directly into every application, and for a single app that is fine. But cron, logwatch, unattended-upgrades and anything else that calls sendmail expect a local mail agent to exist. Installing a small one means all of it works, and there is one place to change credentials.

The lightest option is msmtp with the msmtp-mta package, which provides a sendmail command that everything on the system already knows how to call.

sudo apt install msmtp msmtp-mta

Then /etc/msmtprc:

defaults
auth           on
tls            on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        /var/log/msmtp.log

account        relay
host           smtp.relay.example.net
port           587
from           noreply@example.com
user           apikey
password       REPLACE_ME

account default : relay

That file contains a password, so lock it down before you put the password in it:

sudo chmod 600 /etc/msmtprc
sudo chown root:root /etc/msmtprc

Verify: echo "test body" | mail -s "test" you@somewhere.else arrives, and sudo tail /var/log/msmtp.log shows a line ending in exitcode=EX_OK. If mail is missing, install bsd-mailx.

Step 4: get the From address right

The domain in your From header must be the domain you set up SPF and DKIM for. This sounds obvious and it is the single most common reason a correctly configured relay still lands in spam: the application is sending as www-data@localhost or root@myserver, which matches nothing you published. The mechanism that ties the header to the records is called alignment — DMARC passes when the From: domain is the same organisation as either the envelope domain SPF checked or the d= domain DKIM checked, and it needs only one of the two.

Set the sender explicitly in the application’s own configuration. In msmtp you can also force it, which catches anything that does not:

# add to the account block
from            noreply@example.com
set_from_header on

Use a real, monitored address for Reply-To even if From is a no-reply. People reply to automated mail constantly, and a reply that vanishes is a support problem you never find out about.

Verify: send a test to a Gmail address you control, open the message, and use “Show original”. Read it for alignment rather than for three greens: check that the DKIM-Signature header’s d= value is your domain and not your relay’s, because that is the leg that survives a forward. Three passes is neither the requirement nor a guarantee — DMARC needs one aligned pass, and a message can show SPF pass, DKIM pass and still fail DMARC if both were about domains your relay owns: The Life of an Outbound Email.

Step 5: know when it breaks

Relay credentials get revoked, free tiers get exhausted, DNS records get clobbered during a migration. Very little of that announces itself to you. A permanent rejection does produce a detailed report naming the exact reason — but it is addressed to the envelope sender, which in this arrangement is an address at your relay, so it lands in their mailbox rather than yours. A temporary rejection produces nothing at all for five days.

Two cheap defences, and the first is the one that matters. Find out where your relay puts bounces and make sure somebody reads them — that is where your evidence is going, and every provider has a dashboard showing bounce and complaint rates. And send yourself one scheduled message a week from the server, so that its absence is noticeable.

Verify: disable the relay account deliberately, send a test, and confirm the failure is visible somewhere you actually look — the log, an alert, a monitoring check. Then re-enable it.

Part 2: running a real mail server

If you want to receive mail at your own domain, on hardware you control, this is what the job actually involves. It is genuinely doable. It is also the most demanding self-hosted service there is, and the difficulty is not in the setup.

What the pieces are

PieceJobCommon choice
MTASpeaks SMTP to the outside world, accepts and sendsPostfix
MDA / storeHolds the mailboxes, serves IMAP to your mail clientDovecot
FilterScores incoming mail, rejects the obvious, tags the restRspamd
SigningAdds your DKIM signature on the way outRspamd or OpenDKIM
TLSCertificates for SMTP and IMAP, renewed automaticallyLet’s Encrypt via certbot

Plus an MX record pointing at the host, a matching A record, and a firewall that lets 25, 465, 587 and 993 through. Getting all of that talking takes a determined weekend if you have not done it before.

The part that is actually hard

Configuration is a weekend. Reputation is somebody else’s arithmetic. A brand new IP address has no sending history, and large receivers treat no history as mildly suspicious by default. You earn your way out of that slowly, by sending low volumes of mail that nobody marks as spam. Nobody publishes a warm-up schedule and the ramps you will find in circulation come from relay vendors’ marketing pages; what receivers do publish is a complaint-rate threshold of 0.3%, a bulk-sender line at five thousand messages a day, and a recovery clock of seven consecutive days below that threshold. There is no configuration setting that shortcuts any of it, and one compromised account sending spam for an afternoon undoes weeks of it.

Some specifics worth knowing before you commit:

  • Residential connections are excluded outright. Home IP ranges are on permanent block lists for port 25 delivery, and most consumer ISPs block outbound 25 anyway. A mail server at home can receive, but it cannot deliver directly — it needs a relay for outbound, which is fine, but means you are running Part 1 as well.
  • Your PTR record must match. The reverse DNS for your sending IP has to resolve to the hostname your server announces in HELO, and that hostname must resolve back to the same IP. You set PTR at your hosting provider, not at your DNS registrar. Mismatched or generic PTR is an instant score penalty at nearly every receiver.
  • Some providers do not sell you port 25 at all. Several large cloud providers block outbound 25 on new accounts and will only lift it on request, if at all. Check before you build, not after.
  • An open relay is found within hours. A misconfigured Postfix that accepts mail for arbitrary destinations will be discovered by automated scanning almost immediately and used to send spam, at which point your IP is blocked everywhere and your provider suspends the account.
  • Backups are non-negotiable and different from other backups. Mail is the one service where the data is irreplaceable and arrives continuously. A nightly snapshot means losing up to a day of correspondence you cannot ask anyone to resend.

If you are going to do it anyway

Do not assemble it by hand the first time. The integrated stacks bundle Postfix, Dovecot, Rspamd, certificate handling and a web admin interface with configurations that are already correct together, which removes most of the ways a hand-built server quietly fails.

StackShapeSuits
MailcowDocker Compose, web UI, batteries includedPeople who want a working server and an admin panel
MailuDocker Compose, lighter, configuration-file drivenPeople comfortable editing config, smaller footprint
docker-mailserverSingle container, no web UI, CLI administrationPeople who want to understand every moving part

Run it on a fresh VPS with a clean IP, on a domain you are not yet depending on, and live with it for a month before you migrate anything real. If you can survive a month of receiving and sending on a spare domain without deliverability problems, you can survive the migration. If you cannot, you have learned that cheaply.

See moving an existing service into a container for the general shape of a parallel-run cutover, which applies here as much as anywhere.

The middle option most people should take

You can have mail at your own domain without running a mail server. A hosted mailbox provider handles receiving, spam filtering, storage and deliverability; you point MX at them and keep your address. It costs a few pounds a month per mailbox, and it means your email keeps working while you are on holiday and the server is not.

This is not a lesser choice. Owning the domain is what gives you portability — you can move providers whenever you like and your address is unchanged. Owning the server mostly gives you the ability to be the person who fixes it at 2am.

Checklist

For the relay path in Part 1, which is what most servers need:

  • Relay account created and the sending domain verified in its dashboard
  • Exactly one SPF record on the domain, including the relay
  • DKIM record published with the selector the relay gave you, and the relay signing with d= your domain rather than its own
  • DMARC record at p=none, with a reporting address you will read
  • /etc/msmtprc configured and chmod 600
  • Test message sent, and “Show original” at the receiving end shows DMARC passing on an aligned leg — the d= domain matching your From: domain
  • Application’s From domain matches the domain you published records for
  • A reachable Reply-To, even if From is no-reply
  • You know which mailbox your relay sends bounces to, and somebody reads it
  • Some signal — a log check, a weekly self-test — that tells you when sending has stopped
  • DMARC moved to p=quarantine once the reports are clean

That is a couple of hours of work that will not need attention again for years, which is a very different proposition from Part 2 — and worth being honest with yourself about which one you are signing up for.