tailwart/README.md
Wayne Hayes a9e2a736fc caddy: build via caddyserver.com download URL, not local xcaddy
The xcaddy/Go compile burns ~1GB RAM this VPS can't spare (per ~/docs/caddy.md
"Custom Binary"). Pull the prebuilt L4-enabled binary from the Caddy build
server instead and swap it over the stock binary in the official image. Built
and verified: caddy v2.11.3 with layer4.handlers.proxy + proxy_protocol.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 22:39:33 -04:00

51 lines
2.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# tailwart
> Tailscale × Stalwart. A mailbox with no WAN presence, fronted by a layer-4
> proxy that can live on another machine entirely.
A deliberately over-engineered playground: [Stalwart](https://github.com/stalwartlabs/stalwart)
mail server wired into **Postgres + Redis + Garage S3** at once, deployed as a
Tailscale sidecar, with a separate `caddy-l4` edge that pipes the raw mail ports
over the tailnet. For `infinidim.net`.
See [CLAUDE.md](./CLAUDE.md) for the architecture and the gotchas.
## Layout
```
tailwart/
├── docker-compose.yml # the mailbox: ts-stalwart sidecar + stalwart
├── config/config.toml # Stalwart config — PG + Redis + S3 wiring (strawman)
├── caddy/ # the edge: custom Caddy (caddy-l4) layer-4 mail proxy
│ ├── Dockerfile # pulls prebuilt caddy-l4 binary (caddyserver.com, no local build)
│ ├── caddy.json # :25/465/587/143/993 → stalwart over the tailnet
│ ├── docker-compose.yml # deploy on any public-IP, tailnet, tag:reverse-proxy host
│ └── README.md
├── acl-snippet.hujson # tag:stalwart owner + grants to merge into your policy
├── .env.example # operator surface — copy to .env
└── .gitignore
```
## Quickstart
```bash
cp .env.example .env && $EDITOR .env # fill secrets (see CLAUDE.md prereqs)
# 1. create the stalwart role/db in shared Postgres + the Garage bucket
# (one-off; see CLAUDE.md "Prerequisites")
# 2. admin console: assign tag:stalwart to the OAuth client + paste acl-snippet
# 3. bring up the mailbox (tailnet-only)
docker compose up -d
# 4. bring up the edge (binds public mail ports; can be a different host)
cd caddy && docker compose up -d --build
```
Then point `infinidim.net`'s MX at the edge host, add SPF/DKIM/DMARC, and finish
configuration in Stalwart's web admin (`mail.infinidim.net`).
## Status
Scaffold / strawman. The Stalwart `config.toml` keys need verifying against a
pinned image version before first real boot — treat it as a starting shape, not
a turnkey config.