From 317e7a55792444638ff28b0f93862a1420dc0601 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Thu, 16 Apr 2026 16:58:01 -0400 Subject: [PATCH] fix(deploy): track registry image + default rpast links to https - docker-compose.yml: rspace service now uses localhost:3000/jeffemmett/rspace-online:${IMAGE_TAG:-latest} so CI's `docker pull ... && docker compose up -d --no-build` actually picks up the new image without a manual retag step. - modules/rpast/mod.ts: base URL defaults to https for any non-loopback host, honoring x-forwarded-proto only when set to http|https. Fixes "Open in " links previously emitted as http:// on CF/Traefik. --- docker-compose.yml | 5 ++++- modules/rpast/mod.ts | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2b070a65..4c378753 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,9 @@ services: rspace: - image: rspace-online-rspace:latest + # CI pushes to localhost:3000/jeffemmett/rspace-online: and + # sets IMAGE_TAG via env when running `docker compose up -d --no-build`. + # Falls back to :latest for local rebuilds. + image: localhost:3000/jeffemmett/rspace-online:${IMAGE_TAG:-latest} # build: # context: . # additional_contexts: diff --git a/modules/rpast/mod.ts b/modules/rpast/mod.ts index 5f9ed72a..27a53a04 100644 --- a/modules/rpast/mod.ts +++ b/modules/rpast/mod.ts @@ -51,8 +51,14 @@ async function buildProjection(c: any) { // Derive the public base URL from the request so in-timeline "Open in // rApp" links resolve against the same origin the user arrived from. + // Default to https — rSpace always runs behind Cloudflare/Traefik TLS in + // production. Only fall back to http for loopback dev hosts. const host = c.req.header('x-forwarded-host') ?? c.req.header('host'); - const proto = c.req.header('x-forwarded-proto') ?? (host?.includes('localhost') ? 'http' : 'https'); + const isLocal = !host || /^(localhost|127\.|\[::1\])/i.test(host); + const forwardedProto = c.req.header('x-forwarded-proto'); + const proto = forwardedProto === 'http' || forwardedProto === 'https' + ? forwardedProto + : (isLocal ? 'http' : 'https'); const baseUrl = host ? `${proto}://${host}` : undefined; const sources = await enumerateCreations(space, { modules, from, to });