This commit is contained in:
2026-02-22 12:58:24 -06:00
parent b072083318
commit ee19b5b659
5 changed files with 413 additions and 369 deletions

View File

@@ -19,285 +19,3 @@ autoconfig.bayarea-cc.com, autoconfig.bizmatch.net {
respond "Autodiscover Service Online" 200
}
# Prod: Neue Domains
www.bizmatch.net {
handle /pictures/* {
root * /home/aknuth/git/bizmatch-project/bizmatch-server # Prod-Ordner
file_server
}
# Statische Dateien (CSS, JS, Bilder) lange cachen, da sich der Name bei Änderungen ändert
header /assets/* Cache-Control "public, max-age=31536000, immutable"
header /*.css Cache-Control "public, max-age=31536000, immutable"
header /*.js Cache-Control "public, max-age=31536000, immutable"
# Die index.html und API-Antworten NIEMALS cachen
header /index.html Cache-Control "no-cache, no-store, must-revalidate"
#handle {
# root * /home/aknuth/git/bizmatch-project-prod/bizmatch/dist/bizmatch/browser # Neuer Prod-Dist-Ordner
# try_files {path} {path}/ /index.html
# file_server
#}
handle {
reverse_proxy host.docker.internal:4200
}
log {
output file /var/log/caddy/access.prod.log # Separate Logs
}
encode gzip zstd
}
bizmatch.net {
redir https://www.bizmatch.net{uri} permanent
import email_settings
}
www.qrmaster.net {
handle {
reverse_proxy host.docker.internal:3050
}
log {
output file /var/log/caddy/qrmaster.log
format console
}
encode gzip
}
qrmaster.net {
redir https://www.qrmaster.net{uri} permanent
}
bayarea-cc.com {
# TLS-Direktive entfernen, falls Cloudflare die Verbindung terminiert
# tls {
# dns cloudflare {env.CLOUDFLARE_API_TOKEN}
# }
handle /api {
reverse_proxy host.docker.internal:3001
}
handle {
root * /app
try_files {path} /index.html
file_server
}
log {
output stderr
format console
}
encode gzip
import email_settings
}
www.bayarea-cc.com {
redir https://bayarea-cc.com{uri} permanent
}
setup.bayarea-cc.com {
# Wir setzen das Root-Verzeichnis auf den neuen Pfad im Container
root * /var/www/email-setup
# Webserver-Standardverhalten
file_server
# Wenn jemand nur die Domain aufruft, zeige setup.html
try_files {path} /setup.html
}
cielectrical.bayarea-cc.com {
# wenn du API innerhalb von Next bedienst, weiterleiten an den Next Prozess
handle {
reverse_proxy host.docker.internal:3000
}
log {
output file /var/log/caddy/cielectrical.log
format console
}
encode gzip
}
hamptonbrown.bayarea-cc.com {
# wenn du API innerhalb von Next bedienst, weiterleiten an den Next Prozess
handle {
reverse_proxy host.docker.internal:3010
}
log {
output file /var/log/caddy/hamptonbrown.log
format console
}
encode gzip
}
nqsltd.bayarea-cc.com {
# wenn du API innerhalb von Next bedienst, weiterleiten an den Next Prozess
handle {
reverse_proxy host.docker.internal:3020
}
log {
output file /var/log/caddy/nqsltd.log
format console
}
encode gzip
}
gregknoppcpa.bayarea-cc.com {
# wenn du API innerhalb von Next bedienst, weiterleiten an den Next Prozess
handle {
reverse_proxy host.docker.internal:3030
}
log {
output file /var/log/caddy/gregknoppcpa.log
format console
}
encode gzip
}
buddelectric.bayarea-cc.com {
# wenn du API innerhalb von Next bedienst, weiterleiten an den Next Prozess
handle {
reverse_proxy host.docker.internal:3040
}
log {
output file /var/log/caddy/buddelectric.log
format console
}
encode gzip zstd
}
iitwelders.bayarea-cc.com {
# wenn du API innerhalb von Next bedienst, weiterleiten an den Next Prozess
handle {
reverse_proxy host.docker.internal:8080
}
log {
output file /var/log/caddy/iitwelders.log
format console
}
encode gzip
}
fancytextstuff.com {
# wenn du API innerhalb von Next bedienst, weiterleiten an den Next Prozess
handle {
reverse_proxy host.docker.internal:3010
}
log {
output file /var/log/caddy/fancytext.log
format console
}
encode gzip
}
www.fancytextstuff.com {
redir https://fancytextstuff.com{uri} permanent
}
auth.bizmatch.net {
reverse_proxy https://bizmatch-net.firebaseapp.com {
header_up Host bizmatch-net.firebaseapp.com
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
header_up X-Real-IP {remote_host}
}
}
gitea.bizmatch.net {
reverse_proxy gitea:3500
}
dev.bizmatch.net {
handle /pictures/* {
root * /home/aknuth/git/bizmatch-project/bizmatch-server
file_server
}
handle {
root * /home/aknuth/git/bizmatch-project/bizmatch/dist/bizmatch/browser
try_files {path} {path}/ /index.html
file_server
}
log {
output file /var/log/caddy/access.log {
roll_size 10MB
roll_keep 5
roll_keep_for 48h
}
}
encode gzip
}
api.bizmatch.net {
reverse_proxy host.docker.internal:3001 { # Neu: Proxy auf Prod-Port 3001
header_up X-Real-IP {http.request.header.CF-Connecting-IP}
header_up X-Forwarded-For {http.request.header.CF-Connecting-IP}
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
header_up CF-IPCountry {http.request.header.CF-IPCountry}
}
}
mailsync.bizmatch.net {
reverse_proxy host.docker.internal:5000 {
header_up X-Real-IP {http.request.header.CF-Connecting-IP}
header_up X-Forwarded-For {http.request.header.CF-Connecting-IP}
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
header_up CF-IPCountry {http.request.header.CF-IPCountry}
}
}
# Roundcube für docker-mailserver
app.email-bayarea.com {
reverse_proxy roundcube:80
log {
output stderr
format console
}
encode gzip
}
# Roundcube für docker-mailserver
config.email-bayarea.com {
root * /home/aknuth/git/config-email/frontend/dist
try_files {path} {path}/ /index.html
file_server
log {
output file /var/log/caddy/config-email.log
}
encode gzip
}
# Roundcube für docker-mailserver
api.email-bayarea.com {
reverse_proxy host.docker.internal:3002
log {
output stderr
format console
}
encode gzip
}
annavillesda.org {
# API requests to backend
handle /api/* {
reverse_proxy host.docker.internal:3070
}
# Frontend static files
handle {
root * /home/aknuth/git/annaville-sda-site/dist
try_files {path} {path}/ /index.html
file_server
}
log {
output file /var/log/caddy/access.prod.log
}
encode gzip
}
www.annavillesda.org {
redir https://annavillesda.org{uri} permanent
}
# -----------------
# just for certificate generation
# -----------------
mail.andreasknuth.de {
reverse_proxy nginx-mailcow:8080
}
web.email-bayarea.com {
reverse_proxy nginx-mailcow:8080
}
# Dieser Block dient nur dazu, das Zertifikat für den Mailserver zu beschaffen/erneuern.
mail.email-srvr.com {
respond "Mailserver Certificate Authority is running." 200
}

View File

@@ -23,14 +23,7 @@ services:
- $PWD/email-setup:/var/www/email-setup
- caddy_data:/data
- caddy_config:/config
- /home/aknuth/git/bizmatch-project/bizmatch/dist/bizmatch/browser:/home/aknuth/git/bizmatch-project/bizmatch/dist/bizmatch/browser
- /home/aknuth/git/bizmatch-project-prod/bizmatch/dist/bizmatch/browser:/home/aknuth/git/bizmatch-project-prod/bizmatch/dist/bizmatch/browser
- /home/aknuth/git/bizmatch-project/bizmatch-server/pictures:/home/aknuth/git/bizmatch-project/bizmatch-server/pictures
- /home/aknuth/git/bizmatch-project-prod/bizmatch-server/pictures:/home/aknuth/git/bizmatch-project-prod/bizmatch-server/pictures
- /home/aknuth/git/annaville-sda-site/dist:/home/aknuth/git/annaville-sda-site/dist:ro # ← DAS FEHLT!
- /home/aknuth/git/bay-area-affiliates/dist/bay-area-affiliates/browser:/app
- /home/aknuth/log/caddy:/var/log/caddy
- /home/aknuth/git/config-email/frontend/dist:/home/aknuth/git/config-email/frontend/dist:ro
environment:
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL}

137
caddy/update-caddy-certs.sh Executable file
View File

@@ -0,0 +1,137 @@
#!/bin/bash
# update-caddy-certs.sh
# Liest alle Domains aus dem DMS und generiert die notwendigen
# Caddyfile-Blöcke für Wildcard-Zertifikate.
#
# Die generierten Blöcke werden NICHT automatisch in das Caddyfile geschrieben,
# sondern in eine separate Datei (caddy_mail_certs.conf) ausgegeben,
# die per "import" in das Hauptcaddyfile eingebunden werden kann.
#
# Usage:
# DMS_CONTAINER=mailserver ./update-caddy-certs.sh
# DMS_CONTAINER=mailserver CADDY_DIR=/pfad/zu/caddy ./update-caddy-certs.sh
# DMS_CONTAINER=mailserver DRY_RUN=true ./update-caddy-certs.sh
set -e
DMS_CONTAINER=${DMS_CONTAINER:-"mailserver"}
CADDY_DIR=${CADDY_DIR:-"."} # Verzeichnis wo das Caddyfile liegt
OUTPUT_FILE=${OUTPUT_FILE:-"$CADDY_DIR/mail_certs"} # Ohne Extension - Caddy importiert ohne .conf
DRY_RUN=${DRY_RUN:-"false"}
echo "============================================================"
echo " 📜 Caddy Wildcard-Cert Konfig Generator"
echo " DMS Container: $DMS_CONTAINER"
echo " Output: $OUTPUT_FILE"
[ "$DRY_RUN" = "true" ] && echo " ⚠️ DRY RUN - Keine Dateien werden geschrieben"
echo "============================================================"
# --- Domains aus DMS lesen ---
echo ""
echo "📋 Lese Domains aus DMS..."
DOMAINS=$(docker exec "$DMS_CONTAINER" setup email list 2>/dev/null \
| grep -oP '(?<=@)[^\s]+' \
| sort -u)
if [ -z "$DOMAINS" ]; then
echo "❌ Keine Accounts gefunden!"
exit 1
fi
echo " Gefundene Domains:"
for d in $DOMAINS; do echo " - $d"; done
# --- email-srvr.com immer einschließen (Default-Domain des DMS) ---
EXTRA_DOMAINS="email-srvr.com"
for extra in $EXTRA_DOMAINS; do
if ! echo "$DOMAINS" | grep -q "^${extra}$"; then
DOMAINS="$DOMAINS $extra"
echo " + $extra (Default DMS Domain - immer dabei)"
fi
done
# --- Konfig generieren ---
echo ""
echo "📝 Generiere Caddy-Konfiguration..."
CONTENT=""
CONTENT="${CONTENT}# mail_certs - Automatisch generiert von update-caddy-certs.sh\n"
CONTENT="${CONTENT}# Wildcard-Zertifikate für alle DMS-Domains.\n"
CONTENT="${CONTENT}# Einbinden im Hauptcaddyfile: import mail_certs\n"
CONTENT="${CONTENT}# Generiert: $(date)\n"
CONTENT="${CONTENT}\n"
for domain in $DOMAINS; do
echo " → Block für: $domain"
CONTENT="${CONTENT}# Wildcard-Cert für $domain\n"
CONTENT="${CONTENT}*.${domain}, ${domain} {\n"
CONTENT="${CONTENT} tls {\n"
CONTENT="${CONTENT} dns cloudflare {env.CLOUDFLARE_API_TOKEN}\n"
CONTENT="${CONTENT} }\n"
CONTENT="${CONTENT} respond \"OK\" 200\n"
CONTENT="${CONTENT}}\n"
CONTENT="${CONTENT}\n"
done
# --- Ausgabe ---
if [ "$DRY_RUN" = "true" ]; then
echo ""
echo "--- VORSCHAU (DRY RUN) ---"
printf '%b' "$CONTENT"
echo "--- ENDE VORSCHAU ---"
else
printf '%b' "$CONTENT" > "$OUTPUT_FILE"
echo ""
echo " ✅ Geschrieben: $OUTPUT_FILE"
fi
# --- Prüfen ob Import im Caddyfile vorhanden ---
CADDYFILE="$CADDY_DIR/Caddyfile"
if [ -f "$CADDYFILE" ]; then
if grep -q "import mail_certs" "$CADDYFILE"; then
echo " ✅ 'import mail_certs' bereits im Caddyfile vorhanden."
else
echo ""
echo "⚠️ AKTION ERFORDERLICH:"
echo " 'import mail_certs' fehlt noch im Caddyfile!"
echo " Bitte folgende Zeile am Anfang (nach dem globalen Block) eintragen:"
echo ""
echo " import mail_certs"
echo ""
echo " Oder automatisch einfügen? (y/N)"
read -r answer
if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
# Import nach der ersten Zeile mit "import " einfügen (falls schon welche da sind)
# oder nach dem globalen {} Block
if grep -q "^import " "$CADDYFILE"; then
# Schreibe nach der letzten import-Zeile
sed -i "/^import /a import mail_certs" "$CADDYFILE"
else
# Schreibe nach dem schließenden } des globalen Blocks
sed -i "/^}/a \\\nimport mail_certs" "$CADDYFILE"
fi
echo " ✅ Import eingefügt."
fi
fi
fi
# --- Caddy reload ---
echo ""
echo "============================================================"
echo "🔄 Nächste Schritte:"
echo ""
echo "1. Caddyfile prüfen - 'import mail_certs' muss vorhanden sein"
echo ""
echo "2. Caddy Konfiguration validieren:"
echo " docker exec caddy caddy validate --config /etc/caddy/Caddyfile"
echo ""
echo "3. Caddy neu laden (kein Downtime):"
echo " docker exec caddy caddy reload --config /etc/caddy/Caddyfile"
echo ""
echo "4. Cert-Generierung verfolgen (dauert ~30s pro Domain):"
echo " docker logs -f caddy 2>&1 | grep -i 'certificate\|acme\|tls'"
echo ""
echo "5. Cert-Pfade prüfen:"
echo " ls /var/lib/docker/volumes/caddy_data/_data/caddy/certificates/"
echo " acme-v02.api.letsencrypt.org-directory/"
echo "============================================================"