From b072083318829f261074ab212a83b8bb02cab256 Mon Sep 17 00:00:00 2001 From: Andreas Knuth Date: Sun, 22 Feb 2026 12:19:34 -0600 Subject: [PATCH] caddy --- caddy/Caddyfile | 303 +++++++++++++++++++++++++++++ caddy/Dockerfile.caddy | 13 ++ caddy/docker-compose.yml | 51 +++++ caddy/email-setup/autodiscover.xml | 29 +++ caddy/email-setup/logo.png | Bin 0 -> 1923 bytes caddy/email-setup/setup.html | 122 ++++++++++++ caddy/email.mobileconfig.tpl | 67 +++++++ caddy/email_autodiscover | 97 +++++++++ 8 files changed, 682 insertions(+) create mode 100644 caddy/Caddyfile create mode 100644 caddy/Dockerfile.caddy create mode 100644 caddy/docker-compose.yml create mode 100644 caddy/email-setup/autodiscover.xml create mode 100644 caddy/email-setup/logo.png create mode 100644 caddy/email-setup/setup.html create mode 100644 caddy/email.mobileconfig.tpl create mode 100644 caddy/email_autodiscover diff --git a/caddy/Caddyfile b/caddy/Caddyfile new file mode 100644 index 0000000..eb167b5 --- /dev/null +++ b/caddy/Caddyfile @@ -0,0 +1,303 @@ +{ + email {env.CLOUDFLARE_EMAIL} + acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN} + acme_ca https://acme-v02.api.letsencrypt.org/directory + debug +} +import email_autodiscover +# --------------------------------------------------------- +# Block A: Die dedizierten Autodiscover Domains +# --------------------------------------------------------- +autodiscover.bayarea-cc.com, autodiscover.bizmatch.net, +autodiscover.ruehrgedoens.de, autoconfig.ruehrgedoens.de, +autoconfig.bayarea-cc.com, autoconfig.bizmatch.net { + + # Hier rufen wir das Snippet auf + import email_settings + + # Fallback für Aufrufe auf Root dieser Subdomains + 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 +} diff --git a/caddy/Dockerfile.caddy b/caddy/Dockerfile.caddy new file mode 100644 index 0000000..66d36f1 --- /dev/null +++ b/caddy/Dockerfile.caddy @@ -0,0 +1,13 @@ +# Dockerfile.caddy +ARG CADDY_VERSION=2.9.1 + +FROM caddy:${CADDY_VERSION}-builder AS builder +# Caddy in exakt dieser Version + Plugins bauen +RUN xcaddy build ${CADDY_VERSION} \ + --with github.com/caddy-dns/cloudflare \ + --with github.com/caddyserver/replace-response + +FROM caddy:${CADDY_VERSION} +COPY --from=builder /usr/bin/caddy /usr/bin/caddy +RUN mkdir -p /var/log/caddy + diff --git a/caddy/docker-compose.yml b/caddy/docker-compose.yml new file mode 100644 index 0000000..bbb49e9 --- /dev/null +++ b/caddy/docker-compose.yml @@ -0,0 +1,51 @@ +services: + caddy: + image: custom-caddy:2.9.1-rr1 + container_name: caddy + build: + context: . + dockerfile: Dockerfile.caddy + restart: unless-stopped + ports: + - "80:80" + - "443:443" + extra_hosts: + - 'host.docker.internal:host-gateway' + networks: + - bizmatch + - keycloak + - gitea + - mail_network + volumes: + - $PWD/Caddyfile:/etc/caddy/Caddyfile + - $PWD/email_autodiscover:/etc/caddy/email_autodiscover + - $PWD/email.mobileconfig.tpl:/etc/caddy/email.mobileconfig.tpl + - $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} + +networks: + bizmatch: + external: true + keycloak: + external: true + gitea: + external: true + mail_network: + external: true + +volumes: + caddy_data: + external: true + caddy_config: diff --git a/caddy/email-setup/autodiscover.xml b/caddy/email-setup/autodiscover.xml new file mode 100644 index 0000000..b855f09 --- /dev/null +++ b/caddy/email-setup/autodiscover.xml @@ -0,0 +1,29 @@ + + + + + email + settings + + IMAP + mail.email-srvr.com + 993 + off + + off + on + on + + + SMTP + mail.email-srvr.com + 465 + off + + off + on + on + + + + \ No newline at end of file diff --git a/caddy/email-setup/logo.png b/caddy/email-setup/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..564e44346f9dda40a713a2401ac3d0adacb7bce2 GIT binary patch literal 1923 zcmbVNYgAL$65fXchXRT5Vl)9MK@m`B^Z_0RaIKkldz96OaHm_QzfK{^*~s*)y}&%r~>w-fL!k zxs-hYXhTy&0025D&@WW$Y3PCaEH8Oig;=24g9!N}#jGFYt*lptToZq0)?K*B z3rUfM$3k#Dzq5myU{pE8vJ#06#_-7`C4PPbCzT2_E+^IH%ZwgWsH`C`I3no>Vi)EO z3sEu+($pXYiWPAU=KKST$D~)#6V!=^9)U{=v+TZ6NXn976Cw?V4eJ7^YIYSS4&+n+ zfaNv`_E%R;;N75(nfZd5_?C>2=|;%`3gWzz0fR6+@1kj_9nfvsua=196AO9eo#&e- zJC%Lcf>9Vv4E>$cnD_Te@rzGAmTy;a^w&@moRuwuk<$g=h!&K!^W$?Vc_=e{QB6;5H3nSgdEbUV^G;F@|iI)Qv9NWOiP!Lc0_b;o*{T(5= zt$F`7Q{Hul<(dK*M#w!(GCJ~b*tZ9T;Jfp_r}rv|E;)CrC+|`rGah?#X~~l~O8Jo7 zC*VuiNMYUz0WqRRH>eQPaNaDbkZ5@Tv}5k1964jT?m9=$h`jR(wABTs(2(-(vyw~G z9L*;sQAg7AdR(RJ8QMSC9v}p1C**b?W(Mm+2Y<<1?fi(-wqP$1IhHWYLrjnFc zA*OfcY~HE)YQHP4Jbgc;TuhRrfHy2_6#GhMlFc$*|h8v#;* zpTKXe`pjc?>@GOnf=PILs!%<1jsv$j=M(g$`i$7KQ$IrDUd+pme2KxrO_~Es<2}Ze zHx_$x4mX8Tjg-1y(Gh75N2g5;|D+>09w*)2D+jb7{oNdPO zija^6Z{7er^yo=AWXCGa7u=8p4q;Ii0v&S@djGO54PiXPwY;{&lFM|>k*Y_J!+iTe zae{r1_4OxUBYUG!XK0`YxHFGgFTWXepo z0Frzpl)KdzpJ&Qj!SaoH3QWP3=-hL6WaJA1xSX%% zyq~@2?y+`v47Z)e2xo_a(e6O>oHSNF6z$t%M|$l9M12PMC6B~ZX?rG~HAq|2;wJBJ zp*I}`3B|9eF&`&p#NqYd+2#+9qbjqPpL`<3jPh*(hl%Abl8 z!f9Q72Y&%BsCYJxd@MJElP{#IrecV0{*wWs+dF)7C>8dHqZah+b=ZRII2-h8B zDhp9<3mkCskp1xhRsA>C>o4|h?NGNg>;7$&#l3YR9KRF96yKDPlaRGT6@x}k<3KHX znS)J=1+|LXe})IX8B>e6THN@cUVBHm2uE=x-I9n+-Z}N&t&vkQPF`SZ_3ai0i z!1&@nDo3^BNJLo_J(OpNxU_X}POSNYS*4QB^x#6j3PIu->`KFG7K%Dwib!>5Y(%(Y zmcL<1gHtR|3q_42FftXvN6GX?CNi1dltFvCLa3h09i{hGPD%0L+JuD=UVthW2Rlw? zK_>@x2?@{OT?RAHA1$2>t(LGhT;u|A$-B&p^Q6`#on(BkPoe1liRw?%>ieBA+o-#~ U$TjbrmQ_KJ|31GOAL^O^0NONNhX4Qo literal 0 HcmV?d00001 diff --git a/caddy/email-setup/setup.html b/caddy/email-setup/setup.html new file mode 100644 index 0000000..63c2b5d --- /dev/null +++ b/caddy/email-setup/setup.html @@ -0,0 +1,122 @@ + + + + + + Email Setup + + + + + +
+ + +
+

Email Setup

+

Enter your email address to automatically configure your iPhone or iPad.

+ +
Please enter a valid email address.
+ + + +
+ +
+

Scan me!

+

Open the Camera app on your iPhone and point it at this code.

+ +
+ +

+ Tap the banner that appears at the top.
+ Click "Allow" and then go to Settings to install the profile. +

+ +
+
+ + + + + \ No newline at end of file diff --git a/caddy/email.mobileconfig.tpl b/caddy/email.mobileconfig.tpl new file mode 100644 index 0000000..55c3d8e --- /dev/null +++ b/caddy/email.mobileconfig.tpl @@ -0,0 +1,67 @@ + + + + + PayloadContent + + + EmailAccountDescription + {{.Req.URL.Query.Get "email"}} + EmailAccountName + {{.Req.URL.Query.Get "email"}} + EmailAccountType + EmailTypeIMAP + EmailAddress + {{.Req.URL.Query.Get "email"}} + IncomingMailServerAuthentication + EmailAuthPassword + IncomingMailServerHostName + mail.email-srvr.com + IncomingMailServerPortNumber + 993 + IncomingMailServerUseSSL + + IncomingMailServerUsername + {{.Req.URL.Query.Get "email"}} + OutgoingMailServerAuthentication + EmailAuthPassword + OutgoingMailServerHostName + mail.email-srvr.com + OutgoingMailServerPortNumber + 465 + OutgoingMailServerUseSSL + + OutgoingMailServerUsername + {{.Req.URL.Query.Get "email"}} + PayloadDescription + E-Mail Konfiguration für {{.Req.URL.Query.Get "email"}} + PayloadDisplayName + {{.Req.URL.Query.Get "email"}} + PayloadIdentifier + com.email-srvr.profile.{{.Req.URL.Query.Get "email"}} + PayloadType + com.apple.mail.managed + PayloadUUID + {{uuidv4}} + PayloadVersion + 1 + + + PayloadDescription + Automatische E-Mail Einrichtung für {{.Req.URL.Query.Get "email"}} + PayloadDisplayName + E-Mail Einstellungen + PayloadIdentifier + com.email-srvr.profile.root + PayloadOrganization + IT Support + PayloadRemovalDisallowed + + PayloadType + Configuration + PayloadUUID + {{uuidv4}} + PayloadVersion + 1 + + \ No newline at end of file diff --git a/caddy/email_autodiscover b/caddy/email_autodiscover new file mode 100644 index 0000000..5f9b24f --- /dev/null +++ b/caddy/email_autodiscover @@ -0,0 +1,97 @@ +(email_settings) { + # 1. Autodiscover für Outlook + route /autodiscover/autodiscover.xml { + header Content-Type "application/xml" + # Wir nutzen {header.X-Anchormailbox} um die Email dynamisch einzufügen + respond ` + + + + email + settings + + IMAP + mail.email-srvr.com + 993 + on + {header.X-Anchormailbox} + off + on + on + + + POP3 + mail.email-srvr.com + 995 + on + {header.X-Anchormailbox} + off + on + on + + + SMTP + mail.email-srvr.com + 465 + on + {header.X-Anchormailbox} + off + on + on + + + +` 200 + } + + # 2. JSON Autodiscover (Modern Outlook) - bleibt gleich + route /autodiscover/autodiscover.json { + header Content-Type "application/json" + respond `{ + "Protocol": "AutodiscoverV1", + "Url": "https://autodiscover.bayarea-cc.com/autodiscover/autodiscover.xml" + }` 200 + } + + # 3. Thunderbird Autoconfig - bleibt gleich (dort funktioniert %EMAILADDRESS% ja nativ) + route /mail/config-v1.1.xml { + header Content-Type "application/xml" + respond ` + + + Rackspace Email + + mail.email-srvr.com + 993 + SSL + password-cleartext + %EMAILADDRESS% + + + mail.email-srvr.com + 465 + SSL + password-cleartext + %EMAILADDRESS% + + +` 200 + } + + # NEU: Apple MobileConfig Route + # Aufrufbar über: /apple?email=kunde@domain.de + route /apple { + # KORREKTUR: Wir müssen Caddy sagen, dass er diesen MIME-Type bearbeiten soll! + templates { + mime "application/x-apple-aspen-config" + } + + # Den richtigen MIME-Type setzen + header Content-Type "application/x-apple-aspen-config; charset=utf-8" + + # Pfad zur Datei im Container + root * /etc/caddy + rewrite * /email.mobileconfig.tpl + file_server + } +} \ No newline at end of file