From f19bcc860c2d3519aa4b680b3990092cd190558e Mon Sep 17 00:00:00 2001 From: karim Date: Tue, 2 Jun 2026 13:35:22 +0200 Subject: [PATCH] VPS-Installer: Caddy Auto-HTTPS (Profil) + IPv4-SMTP-Pref einbauen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- stack/caddy/Caddyfile | 13 +++++++++++++ stack/docker-compose.yml | 27 +++++++++++++++++++++++++++ vps-install.sh | 35 ++++++++++++++++++++++++++++++----- 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 stack/caddy/Caddyfile diff --git a/stack/caddy/Caddyfile b/stack/caddy/Caddyfile new file mode 100644 index 0000000..8151ff3 --- /dev/null +++ b/stack/caddy/Caddyfile @@ -0,0 +1,13 @@ +# Reverse-Proxy mit automatischem Let's-Encrypt — nur auf dem VPS aktiv +# (docker compose --profile caddy ...). Die Domains kommen aus der .env. +# +# Voraussetzung: Port 80 + 443 sind offen und WEBMAIL_FQDN / ADMIN_FQDN +# zeigen per A-Record auf diesen Server. Caddy holt/erneuert die Certs selbst. + +{$WEBMAIL_FQDN} { + reverse_proxy snappymail:8888 +} + +{$ADMIN_FQDN} { + reverse_proxy admin-ui:80 +} diff --git a/stack/docker-compose.yml b/stack/docker-compose.yml index 02b7218..48f066f 100644 --- a/stack/docker-compose.yml +++ b/stack/docker-compose.yml @@ -112,3 +112,30 @@ services: 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 diff --git a/vps-install.sh b/vps-install.sh index 0fb0208..5ca7618 100644 --- a/vps-install.sh +++ b/vps-install.sh @@ -32,6 +32,7 @@ RSPAMD_PORT="${RSPAMD_PORT:-11334}" TIMEZONE="${TZ:-Europe/Zurich}" ENABLE_CLAMAV="${ENABLE_CLAMAV:-0}" ENABLE_FAIL2BAN="${ENABLE_FAIL2BAN:-1}" +ENABLE_CADDY="${ENABLE_CADDY:-1}" # VPS: Auto-HTTPS-Reverse-Proxy für Webmail/Admin (Port 80/443) DMS_IMAGE="${DMS_IMAGE:-ghcr.io/docker-mailserver/docker-mailserver:latest}" DEPLOY_DIR="${DEPLOY_DIR:-/opt/dms-stack}" REPO_ARCHIVE="${REPO_ARCHIVE:-https://git.kgva.ch/karim/DOCKERMAILSERVER-LXC/archive/main.tar.gz}" @@ -169,6 +170,12 @@ password = "${RSPAMD_PASSWORD}"; enable_password = "${RSPAMD_PASSWORD}"; EOF +# IPv4 für ausgehenden SMTP bevorzugen (viele VPS haben keine saubere IPv6-Route +# -> sonst "Network is unreachable"-Verzögerungen in der Queue). DMS liest postfix-main.cf. +mkdir -p "$DEPLOY_DIR/docker-data/dms/config" +grep -q 'smtp_address_preference' "$DEPLOY_DIR/docker-data/dms/config/postfix-main.cf" 2>/dev/null || \ + echo 'smtp_address_preference = ipv4' >> "$DEPLOY_DIR/docker-data/dms/config/postfix-main.cf" + # Self-signed-Cert + erstes Postfach VOR dem Start (sonst bricht DMS ab) msg_info "Erzeuge Self-signed-Zertifikat + erstes Postfach ..." mkdir -p "$DEPLOY_DIR/docker-data/certs" "$DEPLOY_DIR/docker-data/dms/config" @@ -186,7 +193,12 @@ grep -q "^${FIRST_EMAIL}|" "$DEPLOY_DIR/docker-data/dms/config/postfix-accounts. # Stack starten + DKIM + SnappyMail # --------------------------------------------------------------------------- msg_info "Baue & starte Stack (kann ein paar Minuten dauern) ..." -( cd "$DEPLOY_DIR" && docker compose up -d --build ) +COMPOSE_PROFILES=() +if [[ "$ENABLE_CADDY" == "1" ]]; then + mkdir -p "$DEPLOY_DIR/docker-data/caddy" + COMPOSE_PROFILES=(--profile caddy) +fi +( cd "$DEPLOY_DIR" && docker compose "${COMPOSE_PROFILES[@]}" up -d --build ) msg_info "Warte auf Mailserver ..." for i in $(seq 1 60); do @@ -215,6 +227,16 @@ fi PUB_IP="$(curl -fsSL https://ipv4.icanhazip.com 2>/dev/null || hostname -I | awk '{print $1}')" +if [[ "$ENABLE_CADDY" == "1" ]]; then + WEBMAIL_URL="https://${WEBMAIL_FQDN}" + ADMIN_URL="https://${ADMIN_FQDN}" + PROXY_NOTE="Caddy (Auto-HTTPS) aktiv — Webmail/Admin laufen über 443, Zertifikate kommen automatisch (Port 80/443 offen + A-Records nötig)." +else + WEBMAIL_URL="http://${PUB_IP:-}:${WEBMAIL_PORT}" + ADMIN_URL="http://${PUB_IP:-}:${ADMIN_PORT}" + PROXY_NOTE="Kein Reverse-Proxy aktiv — Webmail/Admin nur via IP:Port (oder eigenen Proxy davorhängen)." +fi + # --------------------------------------------------------------------------- # Abschluss # --------------------------------------------------------------------------- @@ -227,14 +249,17 @@ ${GN}╔════════════════════════ Server-IP .......... ${PUB_IP:-?} Mailserver ......... $MAIL_FQDN Erstes Postfach .... $FIRST_EMAIL - Webmail ............ http://${PUB_IP:-}:${WEBMAIL_PORT} - Admin-UI ........... http://${PUB_IP:-}:${ADMIN_PORT} (Supabase-Login) - Rspamd-UI .......... http://${PUB_IP:-}:${RSPAMD_PORT} + Webmail ............ ${WEBMAIL_URL} + Admin-UI ........... ${ADMIN_URL} (Supabase-Login) + Rspamd-UI .......... http://${PUB_IP:-}:${RSPAMD_PORT} (nur via Firewall/Tunnel) ${RD}Rspamd-Passwort:${CL} ${RSPAMD_PASSWORD} + Proxy .............. ${PROXY_NOTE} Verwaltung ......... cd ${DEPLOY_DIR} · docker compose ps ${YW}── DNS: Mailhost (einmalig) ──${CL} - A ${MAIL_FQDN}. IN A ${PUB_IP:-} + A ${MAIL_FQDN}. IN A ${PUB_IP:-} + A ${WEBMAIL_FQDN}. IN A ${PUB_IP:-} (für Caddy-HTTPS) + A ${ADMIN_FQDN}. IN A ${PUB_IP:-} (für Caddy-HTTPS) PTR ${PUB_IP:-} -> ${MAIL_FQDN} (in der Hetzner-Console: Server → rDNS) EOF for d in $MAIL_DOMAINS; do