From 6eb792e32f1b3a1a3e94f7af087e8b53c35bfe46 Mon Sep 17 00:00:00 2001 From: KingKDot Date: Sat, 7 Mar 2026 16:19:04 -0600 Subject: [PATCH] hopefully a fix for image loading --- Overlord-Server/src/main-server.ts | 52 +++++++++++++++++++++++++----- README.md | 17 ++++++++++ docker-compose.quickstart.yml | 3 ++ docker-compose.yml | 3 ++ 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/Overlord-Server/src/main-server.ts b/Overlord-Server/src/main-server.ts index ace3292..e6bc7c2 100644 --- a/Overlord-Server/src/main-server.ts +++ b/Overlord-Server/src/main-server.ts @@ -128,6 +128,13 @@ const TLS_KEY_PATH = config.tls.keyPath; const TLS_CA_PATH = config.tls.caPath; const TLS_CERTBOT = config.tls.certbot; +function envFlagEnabled(name: string): boolean { + const value = String(process.env[name] || "").trim().toLowerCase(); + return value === "1" || value === "true" || value === "yes" || value === "on"; +} + +const TLS_OFFLOAD = envFlagEnabled("OVERLORD_TLS_OFFLOAD"); + const pluginLoadedByClient = new Map>(); const pendingPluginEvents = new Map>(); const pluginLoadingByClient = new Map>(); @@ -221,12 +228,27 @@ const pendingScripts = new Map(); async function startServer() { await loadPluginState(); - const tls = await prepareTlsOptions({ - certPath: TLS_CERT_PATH, - keyPath: TLS_KEY_PATH, - caPath: TLS_CA_PATH, - certbot: TLS_CERTBOT, - }); + let tls: + | { + tlsOptions: { cert?: string; key?: string; ca?: string }; + certPathUsed: string; + source: "certbot" | "configured" | "self-signed"; + } + | null = null; + + if (TLS_OFFLOAD) { + logger.warn( + "[TLS] OVERLORD_TLS_OFFLOAD=true: TLS is expected to terminate at an external proxy/load balancer.", + ); + logger.warn("[TLS] Running internal HTTP listener only. Do not expose the container port directly to the internet."); + } else { + tls = await prepareTlsOptions({ + certPath: TLS_CERT_PATH, + keyPath: TLS_KEY_PATH, + caPath: TLS_CA_PATH, + certbot: TLS_CERTBOT, + }); + } const routeDeps = { notificationsConfig: { @@ -349,7 +371,7 @@ async function startServer() { const server = Bun.serve({ port: PORT, hostname: HOST, - tls: tls.tlsOptions, + ...(tls ? { tls: tls.tlsOptions } : {}), idleTimeout: 255, fetch: createHttpFetchHandler({ metrics, @@ -397,7 +419,21 @@ async function startServer() { disconnectTimeoutMs: DISCONNECT_TIMEOUT_MS, }); - logServerStartup(server, tls.certPathUsed, tls.source); + if (tls) { + logServerStartup(server, tls.certPathUsed, tls.source); + } else { + const hostname = server.hostname || "0.0.0.0"; + const port = server.port ?? 0; + logger.info("========================================"); + logger.info("Overlord Server - PROXY TLS OFFLOAD MODE"); + logger.info("========================================"); + logger.info(`HTTP (internal): http://${hostname}:${port}`); + logger.info(`WS (internal): ws://${hostname}:${port}/api/clients/{id}/stream/ws`); + logger.info(""); + logger.info("External access should be HTTPS/WSS via your reverse proxy platform."); + logger.info("Set this mode only when TLS is terminated by the platform (for example Render). "); + logger.info("========================================"); + } } startServer(); diff --git a/README.md b/README.md index f778db0..da818ca 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,23 @@ These can be changed with: It's literally just docker any question chatgpt can answer so don't worry. +## Reverse proxy TLS offload (Render, etc.) + +Some platforms (such as Render Web Services) terminate TLS at the edge and expect your container to serve plain HTTP on the internal port. + +For those platforms, set: + +- `OVERLORD_TLS_OFFLOAD=true` + +Defaults are unchanged. If `OVERLORD_TLS_OFFLOAD` is not set (or false), Overlord keeps its current behavior and serves HTTPS/WSS directly with configured/self-signed/certbot certificates. + +When offload mode is enabled: + +- Container listener is `http://0.0.0.0:$PORT` (internal only) +- External URL should still be `https://...` via your platform proxy +- Health checks should target `http://localhost:$PORT/health` inside the container +- Do not expose the internal container port directly to the public internet + ## Using-Production-packages-(Windows) Build a production-ready package where the server can still build client binaries at runtime: diff --git a/docker-compose.quickstart.yml b/docker-compose.quickstart.yml index fa822e0..0c84487 100644 --- a/docker-compose.quickstart.yml +++ b/docker-compose.quickstart.yml @@ -18,6 +18,9 @@ services: - OVERLORD_TLS_CERT=/app/certs/server.crt - OVERLORD_TLS_KEY=/app/certs/server.key - OVERLORD_TLS_CA= + # Set true only behind a trusted reverse proxy that terminates TLS (for example Render). + # Default false keeps current behavior: Overlord terminates TLS in-process. + - OVERLORD_TLS_OFFLOAD=false # Optional certbot integration (used only when NODE_ENV=production) - OVERLORD_TLS_CERTBOT_ENABLED=false - OVERLORD_TLS_CERTBOT_LIVE_PATH=/etc/letsencrypt/live diff --git a/docker-compose.yml b/docker-compose.yml index f2e899c..ccbff62 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,9 @@ services: OVERLORD_TLS_CERT: ${OVERLORD_TLS_CERT:-/app/certs/server.crt} OVERLORD_TLS_KEY: ${OVERLORD_TLS_KEY:-/app/certs/server.key} OVERLORD_TLS_CA: ${OVERLORD_TLS_CA:-} + # Set true only behind a trusted reverse proxy that terminates TLS (for example Render). + # Default false keeps current behavior: Overlord terminates TLS in-process. + OVERLORD_TLS_OFFLOAD: ${OVERLORD_TLS_OFFLOAD:-false} # Optional certbot integration (used only when NODE_ENV=production) OVERLORD_TLS_CERTBOT_ENABLED: ${OVERLORD_TLS_CERTBOT_ENABLED:-false} OVERLORD_TLS_CERTBOT_LIVE_PATH: ${OVERLORD_TLS_CERTBOT_LIVE_PATH:-/etc/letsencrypt/live}