- MailRouter: существующий ящик получает свою почту, всё остальное (и чужие домены) — в ящик MAIL_CATCH_ALL; раньше ловушка забирала и письма между ящиками стенда - DataInitializer: ящик-ловушка создаётся при старте; случайные пароли — в MAIL_PASSWORDS_FILE (права 600, в образе /app/data/initial-passwords.txt) - docker-compose.jambotron.yml: MAIL_CATCH_ALL=trap@mail.test по умолчанию - README: ловушка, файл паролей, что нужно для staging Jambotron (TCP-проброс SMTP) - тесты: MailRouterTest, DataInitializerTest (33 всего) α Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
2.9 KiB
YAML
81 lines
2.9 KiB
YAML
# Test deploy on Jambotron (v0.2.3 75.3): pick this file in the deploy wizard.
|
|
# Outside, only the web client + API (service "mail", port 8080) through Jambotron's Caddy — give it a domain.
|
|
# SMTP (3025) stays inside the VM's docker network; nothing is sent outside (OUTBOUND_MODE=off).
|
|
# Secrets are generated on the first start into the "secrets" volume — nothing to type in, nothing in git.
|
|
# Mailboxes admin@<MAIL_DOMAINS> and trap@mail.test (catch-all): passwords in /app/data/initial-passwords.txt
|
|
# of the "mail" container (docker exec <mail container> cat /app/data/initial-passwords.txt).
|
|
name: reactive-mail
|
|
|
|
services:
|
|
secrets-init:
|
|
image: alpine:3.20
|
|
restart: "no"
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
umask 077
|
|
for name in DB_PASSWORD JWT_SECRET; do
|
|
[ -s /secrets/$$name ] || head -c 48 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' > /secrets/$$name
|
|
done
|
|
# postgres reads it as uid 70, the app as uid 10001 — readable inside these containers only
|
|
chmod 644 /secrets/DB_PASSWORD /secrets/JWT_SECRET
|
|
volumes:
|
|
- secrets:/secrets
|
|
|
|
db:
|
|
# Debian, not -alpine: on Jambotron staging VMs (Alpine 3.24, kernel 6.18) the Alpine build of postgres
|
|
# dies with "Bus error" even on --version; the Debian build works (2026-11-05)
|
|
image: postgres:17
|
|
restart: unless-stopped
|
|
depends_on:
|
|
secrets-init:
|
|
condition: service_completed_successfully
|
|
environment:
|
|
POSTGRES_DB: mailserver
|
|
POSTGRES_USER: mail
|
|
POSTGRES_PASSWORD_FILE: /run/mail-secrets/DB_PASSWORD
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
- secrets:/run/mail-secrets:ro
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U mail -d mailserver"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
mem_limit: 256m
|
|
|
|
mail:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/Dockerfile
|
|
restart: unless-stopped
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
expose:
|
|
- "8080" # web client + API → domain in Jambotron
|
|
- "3025" # SMTP, inside the network only
|
|
environment:
|
|
DB_HOST: db
|
|
MAILSERVER_SECRETS_DIR: /run/mail-secrets
|
|
MAIL_DOMAINS: ${MAIL_DOMAINS:-mail.test}
|
|
MAIL_HOSTNAME: ${MAIL_HOSTNAME:-mail.test}
|
|
DKIM_DOMAIN: ${MAIL_DOMAINS:-mail.test}
|
|
# mail trap: mail to any address without its own mailbox here (also gmail.com etc.) goes into this mailbox
|
|
MAIL_CATCH_ALL: ${MAIL_CATCH_ALL:-trap@mail.test}
|
|
MAIL_REGISTRATION: ${MAIL_REGISTRATION:-true} # test stand: anyone can create a mailbox in MAIL_DOMAINS (nothing goes outside)
|
|
OUTBOUND_MODE: "off"
|
|
SMTP_AUTH_WITHOUT_TLS: "true" # SMTP is not reachable from outside the VM
|
|
SPF_ENABLED: "false"
|
|
DMARC_ENABLED: "false"
|
|
volumes:
|
|
- data:/app/data
|
|
- secrets:/run/mail-secrets:ro
|
|
mem_limit: 512m
|
|
|
|
volumes:
|
|
secrets:
|
|
pgdata:
|
|
data:
|