tailwart/.env.example
Wayne Hayes 3a9819c3ee docs: capture outbound-relay lessons (IPv6/AAAA trap, SMTP port block, sidecar ACL)
LESSONS.md gains 8-12: container has no IPv6 (AAAA fails before A, no
fallback), host IPv6 != container IPv6, VPS blocks all outbound SMTP
ports (relay over tailnet), sidecar needs a source ACL grant to
initiate, and MtaRoute changes only take effect on restart.

CLAUDE.md and .env.example warn that the smarthost address must be an
IPv4 literal or tailnet IP, never a dual-stack hostname. acl-snippet
adds the tag:stalwart -> tag:mail outbound grant.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 22:43:21 +01:00

85 lines
4.3 KiB
Plaintext
Raw Permalink 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 — operator configuration (Tailscale × Stalwart)
# ============================================================================
# Copy to .env and fill in. The mailbox stack (docker-compose.yml) and the
# edge proxy (caddy/docker-compose.yml) both read their values from here.
#
# Design: Stalwart runs as a Tailscale sidecar with NO WAN presence. A
# layer-4 (TCP) Caddy proxy on a public-IP host pipes the raw mail ports to it
# over the tailnet. The proxy can live on a DIFFERENT machine than the mailbox
# — that's the whole point. See CLAUDE.md.
# ============================================================================
# ----------------------------------------------------------------------------
# Tailscale — same OAuth client as the rest of the tailnet
# ----------------------------------------------------------------------------
# Sidecar advertises tag:stalwart. Assign that tag to the OAuth client on both
# the Devices/Core and Keys/AuthKeys scopes, or node creation 403s at boot.
TS_OAUTH_CLIENT_SECRET=
TS_TAILNET=tailfe8c.ts.net
# MagicDNS hostname for the Stalwart sidecar → reachable at
# ${STALWART_MAGIC_NAME}.${TS_TAILNET} over the tailnet.
STALWART_MAGIC_NAME=stalwart
# ----------------------------------------------------------------------------
# Mail identity
# ----------------------------------------------------------------------------
# The domain you send/receive for, and the public MX/hostname clients connect
# to (its A record points at the EDGE PROXY's public IP, not the mailbox).
STALWART_DOMAIN=infinidim.net
STALWART_HOSTNAME=mail.infinidim.net
# Initial admin password for the Stalwart web console (first boot only).
# Generate: openssl rand -base64 24
STALWART_FALLBACK_ADMIN_SECRET=
# ----------------------------------------------------------------------------
# Over-engineering, part 1/3 — Postgres (shared instance on the tailnet)
# ----------------------------------------------------------------------------
# Stalwart's metadata + full-text store. Create the role/db once (see README).
DB_MAGIC_NAME=the-record-prod
STALWART_DB_NAME=stalwart
STALWART_DB_USER=stalwart
# Generate: openssl rand -base64 24 (avoid / and + if you ever inline it in a URL)
STALWART_DB_PASSWORD=
# ----------------------------------------------------------------------------
# Over-engineering, part 2/3 — Redis (shared instance on the tailnet)
# ----------------------------------------------------------------------------
# Stalwart's in-memory store: distributed rate limits, caches, token revocation.
REDIS_MAGIC_NAME=slo-time-prod
# Use a dedicated logical DB index so we don't collide with the fediverse apps.
STALWART_REDIS_DB=3
# ----------------------------------------------------------------------------
# Over-engineering, part 3/3 — Garage S3 (shared instance on the tailnet)
# ----------------------------------------------------------------------------
# Stalwart's blob store: message bodies, attachments, sieve scripts.
# Reuses the shared Garage access key; needs its own bucket (see README).
GARAGE_MAGIC_NAME=garage
GARAGE_REGION=garage
GARAGE_ACCESS_KEY_ID=
GARAGE_SECRET_ACCESS_KEY=
STALWART_S3_BUCKET=stalwart-mail
# ----------------------------------------------------------------------------
# Outbound delivery
# ----------------------------------------------------------------------------
# Most VPS providers block outbound :25. If yours does, relay through a
# smarthost (host:port). Leave blank to attempt direct MX delivery.
#
# IMPORTANT: Use an IPv4 literal or a tailnet IP — never a dual-stack hostname.
# The container has no IPv6 and will NOT fall back from AAAA to A; any host
# with an AAAA record will fail immediately (os error 101). Relaying over the
# tailnet (100.x:587) sidesteps this entirely and also bypasses VPS SMTP blocks.
STALWART_SMARTHOST=
# ----------------------------------------------------------------------------
# TLS — Stalwart self-manages certs via ACME DNS-01 (works behind the L4 proxy)
# ----------------------------------------------------------------------------
# DNS provider + token for the DNS-01 challenge. Leave blank to instead mount
# a certbot-issued cert (see config/config.toml [certificate]).
STALWART_ACME_PROVIDER=
STALWART_ACME_TOKEN=