Mail Relay π
Paid feature. The Mail Relay is gated by the
orbit_mailflag and requires Orbit Pro or above. See Orbit Pro for the full tier matrix and upgrade flow.
Quazzarβs Mail Relay ships two distinct surfaces in the same page:
- Relay settings β a single SMTP configuration (host, port, username, password, from address) used automatically by Alerts and Backup notifications when they need to send email.
- Mailbox stack (optional) β a curated Postfix / Dovecot / Rspamd docker-compose stub the operator can flip on when they need to host their own mailboxes; managed through the Phase 2 Container Manager.
Opening the Mail page
Dock β Infra β Mail Relay. The console has three tabs:
- Relay settings β pick a provider preset (Mailgun, SendGrid, Postmark, AWS SES) or configure a custom SMTP endpoint. Passwords are sealed with AES-GCM before they touch sqlite.
- Mailboxes β enable the Postfix/Dovecot/Rspamd stack and manage per-domain mailboxes (local_part, quota, password).
- DNS records β MX + SPF + DKIM + DMARC records to paste at your registrar so the stack can send + receive mail reliably.
Relay settings
The relay is a single-row configuration. Any endpoint on the node can
import internal/mail.Sender and call Send(ctx, Email{β¦}) β if the
row is empty (host unset) the call returns ErrRelayNotConfigured so
the caller can fall back to logging.
In practice two callers use the relay today:
- The Alerts rule engine, when an alerting rule fires and the operator has configured an email recipient.
- The Backup notifier, when a scheduled backup job succeeds or fails.
Provider presets
Selecting a preset in the form auto-populates the host + port so the operator only has to type their username + password. The βCustom SMTPβ option leaves every field editable.
| Preset | Host | Port |
|---|---|---|
| Mailgun | smtp.mailgun.org | 587 |
| SendGrid | smtp.sendgrid.net | 587 |
| Postmark | smtp.postmarkapp.com | 587 |
| AWS SES | email-smtp.us-east-1.amazonaws.com | 587 |
| Custom | β | β |
Secrets
The relay password is sealed via internal/crypto/secrets (AES-GCM
with a machine-local key under /etc/quazzar/secrets.key). The GET
response redacts the field to the empty string and exposes a
has_password boolean so the UI can show βsavedβ without leaking the
value.
Mailbox stack
Enabling the mailbox stack provisions three containers via the Phase 2 Container Manager:
- Postfix (boky/postfix) β SMTP ingress on :25 / :587 / :465 with OpenDKIM signing outbound mail.
- Dovecot β IMAP on :143 / :993, reading the same
mail-datavolume Postfix delivers to. - Rspamd β content scanning and anti-spam on :11334.
The whole stack shares three named volumes (mail-config,
mail-data, mail-dkim) so mailbox CRUD performed by the Quazzar
daemon is visible to all three containers without restarts. Mailbox
passwords are sealed at rest and written into /etc/dovecot/users
through docker exec β no plaintext ever touches the host disk.
DNS records
The DNS records tab renders four records the operator must publish at their registrar:
| Type | Name | Purpose |
|---|---|---|
| MX | example.tld | Inbound delivery. |
| TXT | example.tld | SPF sender policy. |
| TXT | quazzar._domainkey.example.tld | DKIM public key. |
| TXT | _dmarc.example.tld | DMARC quarantine policy. |
The DKIM public key is generated at stack-enable time; propagation can take up to 24 h.
Exposing the webmail UI
The stack doesnβt ship a webmail UI by default β we keep it lean. If
you want one, deploy Roundcube / SnappyMail as a regular app in the
Container Manager and route the
public URL through the Phase 1
Reverse Proxy (POST /api/proxy/routes).
Security
- The
/api/mail/*surface requires Orbit Pro and is gated server-side byorbit_mailβ community plans receive the canonical 402 body. - Relay + mailbox passwords are sealed with AES-GCM before they touch sqlite; rotating the master key invalidates every stored password.
- Port 25 is frequently blocked by residential ISPs; delivery to third-party SMTP (Gmail, Outlook) may require a relay through the Relay settings tab even when the mailbox stack is enabled.
Troubleshooting
/api/mail/*returns 402 β Youβre on Community; the feature is paid. Open the upgrade dialog from the lock card.- Outbound mail bounces β Check that SPF + DKIM + DMARC records
have propagated (
dig TXT example.tld); recipients (especially Gmail) reject mail that fails all three. - Container stack wonβt start β Ports 25 / 587 / 465 may already be bound by a host-level Postfix / exim. Disable or remove the host mailer before enabling the Quazzar stack.