agentbbs/deploy/mailu
Anthony Ettinger 807ecf2530
Some checks are pending
CI / build (push) Waiting to run
deploy / deploy (push) Waiting to run
test / test (push) Waiting to run
chore: keep all agentbbs services on latest software (#69)
* ci: add mailu-update workflow to keep the mail stack current

The deploy/mailu compose stack pins the floating series tags
(ghcr.io/mailu/*:2024.06); patch releases within the series only land when
someone runs `docker compose pull`, so the box drifts behind on security fixes.

Add a scheduled (weekly) + on-demand workflow that SSHes to the droplet
(reusing deploy.yml's DEPLOY_* secrets), backs up DKIM keys + the admin DB,
pulls the latest images for the pinned series, recreates the containers, and
health-checks the Mailu front on 127.0.0.1:8080. Shares deploy.yml's
concurrency group so it never races a code deploy. Stays within the pinned
series on purpose — crossing to a future series stays a deliberate PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore: bump Forgejo to 11.0.15 + add Dependabot to keep deps current

Audit of every version pin in the repo: Ergo (2.18.0), Go (1.26 → latest
patch via setup-go), the Ubuntu pod base (24.04 LTS), and the GitHub Action
majors are all already current. Only Forgejo was stale — bump 11.0.1 →
11.0.15 (latest patch of the 11.x LTS line; a 15.x major stays a deliberate,
tested upgrade because of DB migrations).

Add .github/dependabot.yml so github-actions, Go modules, and the Docker
image tags (Mailu compose + pod Containerfile) get review-gated update PRs
weekly. Shell-string pins (FORGEJO_VERSION/ERGO_VERSION in setup.sh) can't be
watched by Dependabot; noted inline. Mailu runtime patch level is handled by
the mailu-update workflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* mailu: document RECIPIENT_DELIMITER=+ in mailu.env.example

Plus-addressing (chovy+tag@ -> chovy@) is a hard prerequisite for qaaas.dev's
packages/mail but was missing from the example, so tagged mail bounces as an
unknown recipient until an operator sets it by hand. Add it with a note that it
governs DELIVERY only, not login (Mailu auths the exact address; base <name>@
is the single login and already receives all +tagged mail).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 20:06:06 -07:00
..
.gitignore Self-host Mailu mail stack at mail.profullstack.com 2026-06-14 16:33:25 +00:00
docker-compose.override.yml.example Feat/mail all members (#55) 2026-06-23 03:38:31 -07:00
docker-compose.yml Self-host Mailu mail stack at mail.profullstack.com 2026-06-14 16:33:25 +00:00
mailu.env.example chore: keep all agentbbs services on latest software (#69) 2026-06-30 20:06:06 -07:00
provision-mailbox.sh Feat/mail all members (#55) 2026-06-23 03:38:31 -07:00
README.md Self-host Mailu mail stack at mail.profullstack.com 2026-06-14 16:33:25 +00:00
refresh-certs.sh Self-host Mailu mail stack at mail.profullstack.com 2026-06-14 16:33:25 +00:00

deploy/mailu — self-hosted mail for mail.profullstack.com

Mailu (Postfix + Dovecot + Roundcube + rspamd) as a Docker Compose stack, fronted by the host Caddy. Full setup, DNS, and architecture: docs/mail.md.

Files

File Purpose
docker-compose.yml the Mailu services (mail ports on host, HTTP on loopback)
mailu.env.example config template → copy to mailu.env and fill secrets
refresh-certs.sh copy Caddy's mail.$DOMAIN cert into Mailu, reload (timer)
provision-mailbox.sh create a member mailbox / the gateway master user

mailu.env, certs/, and data/ are gitignored (secrets + state).

Gateway master user

The agentbbs gateway opens any member's mailbox over IMAP with a single secret, using Dovecot's master user feature (login <name>*<master>). Enable it with a Dovecot override so Mailu accepts the * separator:

data/overrides/dovecot/auth-master.conf:

auth_master_user_separator = *
passdb {
  driver = static
  args = nopassword=y
  master = yes
  result_success = continue
}

Then create the master account and point agentbbs at it:

./provision-mailbox.sh --master "$(openssl rand -hex 16)"
# AGENTBBS_MAIL_MASTER_USER=gateway, AGENTBBS_MAIL_MASTER_PASS=<that secret>

The exact master-passdb wiring varies by Mailu version; verify against your pinned image before relying on it in production. SMTP submission from the gateway uses the trusted local relay (127.0.0.1:25), not the master user.

Ops

docker compose up -d            # start
docker compose logs -f smtp     # tail Postfix
docker compose exec admin flask mailu config-export   # DKIM keys, etc.
docker compose down             # stop