From f6263ad2f3ff33921448e6dc39f88c7f251c82a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Br=C3=BCckner?= Date: Mon, 8 Jun 2026 14:43:29 +0200 Subject: [PATCH] feat(caddy): support HTTPS upstreams via https:// prefix When a route's upstream starts with https://, buildCaddyfile emits a transport http { tls_insecure_skip_verify } block so Caddy connects over TLS and accepts the self-signed certificate typical of backends like Semaphore. Added a UI hint explaining the https:// prefix. --- ARCHITECTURE.md | 3 +++ server.ts | 12 +++++++++++- src/components/Settings.tsx | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index f6c2cdd..b018356 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -464,6 +464,9 @@ Manual: POST /api/semaphore/trigger/{bookingId} body { type: 'setup'|'teardown buildCaddyfile(): { local_certs } # global block per custom route { [encode] [tls internal] reverse_proxy } + upstream prefixed with https:// → reverse_proxy gets a + transport http { tls_insecure_skip_verify } block + (for self-signed TLS backends like Semaphore) importCaddyfileRoutes(): reads /etc/caddy/Caddyfile on first Caddy enable parses hostname/upstream blocks → seeds caddy table as custom routes diff --git a/server.ts b/server.ts index ddab153..030ac6a 100644 --- a/server.ts +++ b/server.ts @@ -82,7 +82,17 @@ function buildCaddyfile(): string { lines.push(`${route.hostname} {`); if (route.compress) lines.push(' encode zstd gzip'); if (route.tls) lines.push(' tls internal'); - lines.push(` reverse_proxy ${route.upstream}`); + if (/^https:\/\//i.test(route.upstream)) { + // HTTPS upstream (e.g. Semaphore) — connect over TLS and skip certificate + // verification, since such backends typically use a self-signed cert. + lines.push(` reverse_proxy ${route.upstream} {`); + lines.push(' transport http {'); + lines.push(' tls_insecure_skip_verify'); + lines.push(' }'); + lines.push(' }'); + } else { + lines.push(` reverse_proxy ${route.upstream}`); + } lines.push('}', ''); } diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index d26ee85..0a763d9 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -930,6 +930,7 @@ export default function Settings({ currentUser: _currentUser }: SettingsProps) { {caddyEnabled && (
+ Prefix the upstream with https:// for TLS backends (e.g. Semaphore) — the certificate is not verified. {caddyStatus === 'unavailable' && (