The real first step: installing Postfix, understanding the anatomy of main.cf, getting to know key parameters like myhostname, myorigin, mydestination, mynetworks, inet_interfaces, and relayhost, then running and verifying the service via postconf, postfix check, and postfix reload.

The architecture map was drawn in episode 2. Now we get our hands dirty: Postfix installation and basic configuration. This episode is the foundation for everything that follows — DNS, TLS, virtual users, and anti-spam all attach to Postfix.
We'll install the Postfix package, dissect main.cf as the center of configuration, get to know the key parameters, then learn to verify the configuration with postconf and postfix check. By the end of the episode, your Postfix will be running as a healthy local MTA.
Postfix is available in the repositories of all major distributions. For Debian/Ubuntu:
sudo apt update
sudo apt install -y postfixDuring installation on Debian, you'll be asked about the configuration type. Choose Internet Site — this prepares main.cf with sensible initial values. If the installation finishes without a prompt (for example because it's non-interactive), don't worry; we'll adjust everything through postconf.
Once installed, verify the service is running:
systemctl status postfix --no-pager
postconf mail_versionpostconf mail_version displays the active Postfix version — usually 3.11.5 on the latest 2026 distributions. Note the number; we'll discuss the version ecosystem in episode 21.
All of Postfix's core policy lives in /etc/postfix/main.cf. The format is simple: parameter = value, one per line, with whitespace around the equals sign being optional. Blank lines are ignored, and values can be continued with indentation.
Don't edit this file manually if you can avoid it — almost every change we make in this series uses postconf -e, which rewrites main.cf safely and keeps a consistent format:
sudo postconf -e 'myhostname = mail.example.com'
sudo postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost'Note the use of $myhostname and $mydomain — Postfix supports referencing other parameters, keeping the configuration concise and consistent.
The following six parameters are Postfix's alphabet. Get to know all of them before continuing.
The hostname Postfix considers its own identity. Set it to a full FQDN, for example mail.example.com. All banners, Message-IDs, and Received: headers use this value.
The domain inserted into email sent without an explicit domain — for example from local commands. Common values: $myhostname or $mydomain.
The list of domains considered "local" — Postfix will accept email for these domains and deliver it to local mailboxes. In a virtual architecture (episode 7), this list shrinks dramatically, but for now leave the defaults.
The list of networks trusted to relay without authentication — usually 127.0.0.0/8 and your internal network segments. Never add public networks here, or you'll open an open relay (episode 16).
The interfaces Postfix listens on. all means all interfaces; loopback-only restricts to local. For a public mail server, all is the answer.
The host used to forward all outbound email. Empty means deliver directly to the destination. If you use a provider's SMTP relay, set it here — episode 18 discusses enforcing TLS to the relay.
postconf has two main modes: with -d it shows the built-in default values, without arguments it shows the active values resulting from defaults + configuration:
postconf myhostname mydestination mynetworks
postconf -d smtpd_bannerThe first line shows the three parameters we just learned; the second shows the built-in default of smtpd_banner. The habit of checking values with postconf will save you from guessing during debugging.
After changing the configuration, run the two mandatory rituals:
sudo postfix check
sudo postfix reloadpostfix check verifies the syntax and consistency of the entire configuration — if there's a problematic line, it reports it before you break a running service. postfix reload applies the configuration without stopping the queue.
Warning
Never use postfix start when the service is already managed by systemd. Use sudo systemctl reload postfix or sudo postfix reload. Starting a second instance will trigger a socket conflict that makes the queue inconsistent.
Test basic acceptance by sending an email to a local user:
echo "test" | mail -s "Hello" rootThen check the queue and logs to make sure the message was delivered:
postqueue -p
journalctl -u postfix --since "1 minute ago"If the queue is empty and the log shows status=sent, your basic Postfix is working.
Episode 3 is done. Key takeaways:
main.cf is the center of configuration; change it via postconf -e, not manual editing.myhostname, myorigin, mydestination, mynetworks, inet_interfaces, and relayhost are the core parameters.postconf shows active values; postconf -d shows built-in defaults.postfix check before reloading, and let systemd manage the service.Postfix is standing. In episode 4 we install its equally important partner: Dovecot — the IMAP/POP3 server that will store your mailboxes — complete with the dovecot.conf configuration structure, the mail_location parameter, and verification via doveconf -n. See you in episode 4!