f19bcc860c
- caddy-Service in docker-compose (profiles: caddy) – reverse-proxyt webmail/admin mit automatischem Let's-Encrypt; auf dem LXC bleibt er aus (dort macht NPM das HTTPS) - stack/caddy/Caddyfile (Domains via WEBMAIL_FQDN/ADMIN_FQDN aus .env) - vps-install.sh: ENABLE_CADDY (default 1) -> --profile caddy beim Deploy, smtp_address_preference=ipv4 als postfix-main.cf-Override (gegen IPv6- 'Network unreachable'-Queue-Delays), Output mit https-URLs + A-Records Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
142 lines
4.8 KiB
YAML
142 lines
4.8 KiB
YAML
# ============================================================================
|
||
# docker-mailserver Stack
|
||
# mailserver – Postfix/Dovecot/Rspamd (docker-mailserver)
|
||
# admin-api – Node.js API (Supabase-Auth) verwaltet DMS-Config-Dateien
|
||
# admin-ui – React-Admin Oberfläche (nginx, proxyt /api -> admin-api)
|
||
# snappymail – schlankes Webmail für die Mitarbeiter
|
||
#
|
||
# TLS/HTTPS für admin-ui & snappymail macht der Nginx Proxy Manager
|
||
# (separater Stack), der auf ADMIN_PORT / WEBMAIL_PORT dieses Hosts zeigt.
|
||
# ============================================================================
|
||
services:
|
||
mailserver:
|
||
image: ghcr.io/docker-mailserver/docker-mailserver:${DMS_TAG:-latest}
|
||
container_name: mailserver
|
||
hostname: ${MAIL_FQDN}
|
||
env_file: mailserver.env
|
||
environment:
|
||
- OVERRIDE_HOSTNAME=${MAIL_FQDN}
|
||
- POSTMASTER_ADDRESS=postmaster@${MAIL_DOMAIN}
|
||
ports:
|
||
- "25:25" # SMTP (eingehender MX-Verkehr)
|
||
- "143:143" # IMAP (STARTTLS)
|
||
- "465:465" # SMTP Submission (implicit TLS)
|
||
- "587:587" # SMTP Submission (STARTTLS)
|
||
- "993:993" # IMAP (implicit TLS)
|
||
- "${RSPAMD_PORT:-11334}:11334" # Rspamd Web-UI — NUR über NPM/Firewall öffnen!
|
||
volumes:
|
||
- ./docker-data/dms/mail-data/:/var/mail/
|
||
- ./docker-data/dms/mail-state/:/var/mail-state/
|
||
- ./docker-data/dms/mail-logs/:/var/log/mail/
|
||
- ./docker-data/dms/config/:/tmp/docker-mailserver/
|
||
- ./docker-data/certs/:/etc/letsencrypt/:ro # Zertifikate (NPM DNS-Challenge)
|
||
- /etc/localtime:/etc/localtime:ro
|
||
restart: always
|
||
stop_grace_period: 1m
|
||
cap_add:
|
||
- NET_ADMIN # für Fail2ban
|
||
healthcheck:
|
||
test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"
|
||
timeout: 3s
|
||
retries: 0
|
||
|
||
# docker-socket-proxy: gibt der Admin-API NUR exec frei (kein create/delete/...)
|
||
socket-proxy:
|
||
image: tecnativa/docker-socket-proxy:latest
|
||
container_name: dms-socket-proxy
|
||
restart: always
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
environment:
|
||
- CONTAINERS=1
|
||
- EXEC=1
|
||
- POST=1
|
||
volumes:
|
||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||
|
||
admin-api:
|
||
build: ./api
|
||
container_name: dms-admin-api
|
||
restart: always
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
environment:
|
||
- CONFIG_DIR=/config
|
||
- MAIL_DOMAIN=${MAIL_DOMAIN}
|
||
- MAIL_DOMAINS=${MAIL_DOMAINS}
|
||
- MAIL_FQDN=${MAIL_FQDN}
|
||
- BRAND=${BRAND}
|
||
- WEBMAIL_FQDN=${WEBMAIL_FQDN}
|
||
- ADMIN_FQDN=${ADMIN_FQDN}
|
||
- SUPABASE_URL=${SUPABASE_URL}
|
||
- SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
|
||
- ADMIN_ALLOWED_EMAILS=${ADMIN_ALLOWED_EMAILS}
|
||
# Bridge zum Mailserver: nur exec über den socket-proxy, Whitelist in der API
|
||
- DOCKER_PROXY=socket-proxy:2375
|
||
- MAILSERVER_CONTAINER=mailserver
|
||
depends_on:
|
||
- socket-proxy
|
||
volumes:
|
||
# Schreibzugriff auf die DMS-Config-Dateien (kein direkter Docker-Socket!)
|
||
- ./docker-data/dms/config/:/config/
|
||
expose:
|
||
- "3000"
|
||
|
||
admin-ui:
|
||
build:
|
||
context: ./admin
|
||
args:
|
||
# Werden zur Laufzeit via /config.js injiziert (siehe entrypoint)
|
||
- VITE_SUPABASE_URL=${SUPABASE_URL}
|
||
- VITE_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
|
||
container_name: dms-admin-ui
|
||
restart: always
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
depends_on:
|
||
- admin-api
|
||
environment:
|
||
- SUPABASE_URL=${SUPABASE_URL}
|
||
- SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
|
||
ports:
|
||
- "${ADMIN_PORT:-8080}:80"
|
||
|
||
snappymail:
|
||
image: djmaze/snappymail:latest
|
||
container_name: snappymail
|
||
restart: always
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
ports:
|
||
- "${WEBMAIL_PORT:-8888}:8888"
|
||
volumes:
|
||
- ./docker-data/snappymail/:/var/lib/snappymail/ # echter Datenpfad der djmaze-Image
|
||
- ./snappymail-theme/:/snappymail/themes/:ro # KGVA "Shibui"-Theme
|
||
|
||
# ----------------------------------------------------------------------------
|
||
# caddy – Reverse-Proxy mit automatischem Let's-Encrypt (NUR auf dem VPS).
|
||
# Aktivieren via Profil: docker compose --profile caddy up -d
|
||
# Auf dem LXC bleibt er AUS (dort macht der Nginx Proxy Manager das HTTPS).
|
||
# Domains kommen aus der .env (WEBMAIL_FQDN / ADMIN_FQDN); Caddy holt sich
|
||
# die Zertifikate selbst (Port 80/443 müssen offen sein).
|
||
# ----------------------------------------------------------------------------
|
||
caddy:
|
||
image: caddy:2-alpine
|
||
container_name: dms-caddy
|
||
profiles: ["caddy"]
|
||
restart: always
|
||
security_opt:
|
||
- no-new-privileges:true
|
||
ports:
|
||
- "80:80"
|
||
- "443:443"
|
||
environment:
|
||
- WEBMAIL_FQDN=${WEBMAIL_FQDN}
|
||
- ADMIN_FQDN=${ADMIN_FQDN}
|
||
volumes:
|
||
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||
- ./docker-data/caddy/:/data/
|
||
depends_on:
|
||
- snappymail
|
||
- admin-ui
|