Members get a real <name>@mail.profullstack.com mailbox, served by a
co-located Mailu (Postfix+Dovecot+Roundcube+rspamd) Docker stack. Coexists
with the host Caddy: Mailu owns the mail ports; Caddy fronts the loopback
webmail and supplies the TLS cert (TLS_FLAVOR=mail), the same cert-copy
pattern as the Ergo/IRC and NNTP services.
- deploy/mailu/: docker-compose.yml, mailu.env.example, refresh-certs.sh
(copy Caddy's mail cert into Mailu on renewal), provision-mailbox.sh
(member mailbox + Dovecot gateway master user), README.
- setup.sh: MAIL flag + mail.${DOMAIN#*.} Caddy site + §9e (cert timer,
mail-port firewall, conditional compose bring-up, AGENTBBS_MAIL_* env).
- docs/mail.md: architecture, DNS (MX/SPF/DKIM/DMARC/PTR), gateway
master-user setup, env, provisioning, webmail-only policy.
Apex profullstack.com stays corporate; member mail is only on mail.*.
Infra is inspection-verified (bash -n, YAML lint); deploy pending.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.9 KiB
Mail — self-hosted Mailu at mail.profullstack.com
AgentBBS gives Founding Lifetime (paid) members a real mailbox at
<name>@mail.profullstack.com, reached two ways:
- Webmail —
https://mail.profullstack.com(Roundcube), the only member-facing mail surface. - AgentMail — the in-BBS client (
internal/mailbox): theMailhub entry orssh mail@bbs.profullstack.com(a TUI for humans, a JSON bot mode for agents). It connects to this stack.
The apex profullstack.com is reserved for corporate mail and is not served
here — member mail lives only on the mail. subdomain.
Architecture
The host already runs Caddy (owns :80/:443) and the agentbbs process.
Mailu (Postfix + Dovecot + Roundcube + rspamd) runs as a Docker Compose stack:
- Mailu owns the mail ports on the host:
25, 465, 587, 993, 995. - Mailu's HTTP front is bound to loopback (
127.0.0.1:8080); Caddy reverse-proxieshttps://mail.profullstack.comto it (webmail + admin). - TLS:
TLS_FLAVOR=mail— Mailu does not run its own ACME (Caddy is the only ACME client). Caddy obtains themail.profullstack.comcert from its site block;deploy/mailu/refresh-certs.shcopies it into Mailu and reloads it on renewal — the same pattern as the Ergo/IRC and NNTP cert refreshers. - The agentbbs gateway reads/sends on behalf of members: IMAP via a Dovecot
master user (one secret opens any mailbox), SMTP via the co-located relay
on
127.0.0.1:25. Members therefore never manage an IMAP/SMTP password.
┌─────────── Caddy (:443) ───────────┐
webmail → │ mail.profullstack.com → 127.0.0.1:8080 (Mailu front, HTTP)
└───────────────┬─────────────────────┘
│ copies LE cert (refresh-certs.sh)
clients → Mailu front (:25 :465 :587 :993 :995) ──→ Postfix / Dovecot / rspamd
▲
agentbbs ──IMAP 993 (master user)──┘ ──SMTP 127.0.0.1:25 (local relay)──▶
DNS
mail.profullstack.com and smtp.profullstack.com A records are added. Also set:
| Type | Host | Value |
|---|---|---|
| A | mail.profullstack.com |
host IP |
| A | smtp.profullstack.com |
host IP |
| MX | mail.profullstack.com |
10 mail.profullstack.com. |
| TXT (SPF) | mail.profullstack.com |
v=spf1 mx -all |
| TXT (DMARC) | _dmarc.mail.profullstack.com |
v=DMARC1; p=quarantine; rua=mailto:postmaster@mail.profullstack.com |
| TXT (DKIM) | dkim._domainkey.mail.profullstack.com |
from flask mailu config-export after first boot |
| PTR | host IP | mail.profullstack.com (set at your VPS provider) |
Port 25 / deliverability: many cloud providers block outbound
:25by default — request an unblock, set the PTR/rDNS, and warm the IP, or relay outbound through a smarthost. Inbound MX and the gateway's local submission work regardless.
Install
cd /opt/agentbbs/deploy/mailu
cp mailu.env.example mailu.env # fill SECRET_KEY, INITIAL_ADMIN_PW, etc.
docker compose up -d
# seed the gateway master user + (optionally) backfill member mailboxes:
AGENTBBS_MAIL_MASTER_USER=gateway ./provision-mailbox.sh --master "$(openssl rand -hex 16)"
Add the Caddy site (setup.sh writes this when MAIL=1):
mail.profullstack.com {
encode zstd gzip
reverse_proxy 127.0.0.1:8080
}
Then install the cert refresher on a timer (setup.sh does this too):
install -m 0755 deploy/mailu/refresh-certs.sh /usr/local/bin/agentbbs-mailu-certs
# systemd timer runs it every ~12h; first run swaps in the real cert once Caddy issues it.
agentbbs gateway env
Set these on the agentbbs service so the Mail hub entry / ssh mail@ work:
| Var | Value |
|---|---|
AGENTBBS_MAIL_DOMAIN |
mail.profullstack.com |
AGENTBBS_MAIL_IMAP_ADDR |
mail.profullstack.com:993 |
AGENTBBS_MAIL_SMTP_ADDR |
127.0.0.1:25 |
AGENTBBS_MAIL_MASTER_USER |
gateway |
AGENTBBS_MAIL_MASTER_PASS |
the master password set above |
Provisioning member mailboxes
A mailbox must exist before the gateway can open it. Provision when a member becomes paid (or backfill):
deploy/mailu/provision-mailbox.sh alice # creates alice@mail.profullstack.com
The Dovecot master user (gateway) then authenticates as any member with
the login form alice*gateway + the master password — which is exactly what
internal/mailbox's IMAP adapter sends. See
deploy/mailu/README.md for the master-user
override and operational details.
Webmail only for members
Members are pointed at https://mail.profullstack.com (Roundcube) and the BBS
Mail client — they are not given the Mailu admin UI or alias management. Admin
is operator-only.