From 6c6eda129a8afc8b5ce2f9812b70911ed1ff1c1e Mon Sep 17 00:00:00 2001 From: Victor Santos Date: Mon, 15 Dec 2025 16:41:51 -0300 Subject: [PATCH] refactor: remove CDN_HOST references from Dockerfiles and entrypoint, streamline asset loading configuration --- Dockerfile.fips.standalone-infisical | 9 +--- Dockerfile.standalone-infisical | 9 +--- backend/src/lib/config/env.ts | 1 + backend/src/server/plugins/serve-ui.ts | 51 +++++++++++++++---- .../replace-standalone-build-variable.sh | 11 +--- frontend/vite.config.ts | 17 ++----- standalone-entrypoint.sh | 10 ---- 7 files changed, 51 insertions(+), 57 deletions(-) diff --git a/Dockerfile.fips.standalone-infisical b/Dockerfile.fips.standalone-infisical index 2c7ce04d91..78deaf73ac 100644 --- a/Dockerfile.fips.standalone-infisical +++ b/Dockerfile.fips.standalone-infisical @@ -2,8 +2,6 @@ ARG POSTHOG_HOST=https://app.posthog.com ARG POSTHOG_API_KEY=posthog-api-key ARG INTERCOM_ID=intercom-id ARG CAPTCHA_SITE_KEY=captcha-site-key -# CDN HOST placeholder - replaced at container startup with actual CDN_HOST env var -ARG CDN_HOST=__INFISICAL_CDN_HOST__ FROM node:20.19.5-trixie-slim AS base @@ -38,8 +36,6 @@ ARG INFISICAL_PLATFORM_VERSION ENV VITE_INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION ARG CAPTCHA_SITE_KEY ENV VITE_CAPTCHA_SITE_KEY $CAPTCHA_SITE_KEY -ARG CDN_HOST -ENV VITE_CDN_HOST $CDN_HOST ENV NODE_OPTIONS="--max-old-space-size=8192" @@ -189,10 +185,7 @@ COPY --from=backend-runner /app /backend COPY --from=frontend-runner /app ./backend/frontend-build -# Copy CDN HOST replacement script for runtime CDN HOST replacement -COPY frontend/scripts/replace-standalone-build-variable.sh /backend/scripts/replace-standalone-build-variable.sh -RUN chmod +x /backend/scripts/export-assets.sh /backend/scripts/replace-standalone-build-variable.sh -RUN chown -R non-root-user:nodejs /backend/frontend-build +RUN chmod +x /backend/scripts/export-assets.sh ARG INFISICAL_PLATFORM_VERSION ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION diff --git a/Dockerfile.standalone-infisical b/Dockerfile.standalone-infisical index 91b7e78c8b..71a6ce6fea 100644 --- a/Dockerfile.standalone-infisical +++ b/Dockerfile.standalone-infisical @@ -2,8 +2,6 @@ ARG POSTHOG_HOST=https://app.posthog.com ARG POSTHOG_API_KEY=posthog-api-key ARG INTERCOM_ID=intercom-id ARG CAPTCHA_SITE_KEY=captcha-site-key -# CDN HOST placeholder - replaced at container startup with actual CDN_HOST env var -ARG CDN_HOST=__INFISICAL_CDN_HOST__ FROM node:20.19.5-trixie-slim AS base @@ -40,8 +38,6 @@ ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION ENV VITE_INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION ARG CAPTCHA_SITE_KEY ENV VITE_CAPTCHA_SITE_KEY $CAPTCHA_SITE_KEY -ARG CDN_HOST -ENV VITE_CDN_HOST $CDN_HOST ENV NODE_OPTIONS="--max-old-space-size=8192" # Build @@ -178,10 +174,7 @@ ENV CAPTCHA_SITE_KEY=$CAPTCHA_SITE_KEY COPY --from=backend-runner /app /backend COPY --from=frontend-runner /app ./backend/frontend-build -# Copy CDN HOST replacement script for runtime CDN HOST replacement -COPY frontend/scripts/replace-standalone-build-variable.sh /backend/scripts/replace-standalone-build-variable.sh -RUN chmod +x /backend/scripts/export-assets.sh /backend/scripts/replace-standalone-build-variable.sh -RUN chown -R non-root-user:nodejs /backend/frontend-build +RUN chmod +x /backend/scripts/export-assets.sh ARG INFISICAL_PLATFORM_VERSION ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index 14eb601925..c47506514e 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -229,6 +229,7 @@ const envSchema = z CAPTCHA_SECRET: zpStr(z.string().optional()), CAPTCHA_SITE_KEY: zpStr(z.string().optional()), INTERCOM_ID: zpStr(z.string().optional()), + CDN_HOST: zpStr(z.string().optional()), // TELEMETRY OTEL_TELEMETRY_COLLECTION_ENABLED: zodStrBool.default("false"), diff --git a/backend/src/server/plugins/serve-ui.ts b/backend/src/server/plugins/serve-ui.ts index 633b4211a3..7b56a957b5 100644 --- a/backend/src/server/plugins/serve-ui.ts +++ b/backend/src/server/plugins/serve-ui.ts @@ -1,6 +1,8 @@ +import fs from "node:fs"; import path from "node:path"; import staticServe from "@fastify/static"; +import RE2 from "re2"; import { getConfig, IS_PACKAGED } from "@app/lib/config/env"; @@ -15,6 +17,9 @@ export const registerServeUI = async ( dir: string; } ) => { + const appCfg = getConfig(); + const cdnHost = appCfg.CDN_HOST || ""; + // use this only for frontend runtime static non-sensitive configuration in standalone mode // that app needs before loading like posthog dsn key // for most of the other usecase use server config @@ -25,15 +30,26 @@ export const registerServeUI = async ( hide: true }, handler: (_req, res) => { - const appCfg = getConfig(); void res.type("application/javascript"); const config = { CAPTCHA_SITE_KEY: appCfg.CAPTCHA_SITE_KEY, POSTHOG_API_KEY: appCfg.POSTHOG_PROJECT_API_KEY, INTERCOM_ID: appCfg.INTERCOM_ID, - TELEMETRY_CAPTURING_ENABLED: appCfg.TELEMETRY_ENABLED + TELEMETRY_CAPTURING_ENABLED: appCfg.TELEMETRY_ENABLED, + CDN_HOST: cdnHost }; - const js = `window.__INFISICAL_RUNTIME_ENV__ = Object.freeze(${JSON.stringify(config)});`; + // Define window.__toCdnUrl for Vite's experimental.renderBuiltUrl runtime support + // This function is called by dynamically imported chunks to resolve CDN URLs + const js = ` +window.__INFISICAL_RUNTIME_ENV__ = Object.freeze(${JSON.stringify(config)}); +window.__toCdnUrl = function(filename) { + var cdnHost = window.__INFISICAL_RUNTIME_ENV__.CDN_HOST || ""; + if (cdnHost && filename.startsWith("assets/")) { + return cdnHost + "/" + filename; + } + return "/" + filename; +}; +`.trim(); return res.send(js); } }); @@ -41,6 +57,23 @@ export const registerServeUI = async ( if (standaloneMode) { const frontendName = IS_PACKAGED ? "frontend" : "frontend-build"; const frontendPath = path.join(dir, frontendName); + + const indexHtmlPath = path.join(frontendPath, "index.html"); + let indexHtml = fs.readFileSync(indexHtmlPath, "utf-8"); + + if (cdnHost) { + // Replace relative asset paths with CDN URLs in script and link tags + indexHtml = indexHtml + .replace(/src="\/assets\//g, `src="${cdnHost}/assets/`) + .replace(/href="\/assets\//g, `href="${cdnHost}/assets/`); + + const cspDirectives = ["script-src", "style-src", "font-src", "connect-src"]; + for (const directive of cspDirectives) { + const regex = new RE2(`(${directive}\\s+'self')`, "g"); + indexHtml = indexHtml.replace(regex, `$1 ${cdnHost}`); + } + } + await server.register(staticServe, { root: frontendPath, wildcard: false, @@ -60,12 +93,12 @@ export const registerServeUI = async ( return; } - return reply.sendFile("index.html", { - immutable: false, - maxAge: 0, - lastModified: false, - etag: false - }); + return reply + .type("text/html") + .header("Cache-Control", "no-cache, no-store, must-revalidate") + .header("Pragma", "no-cache") + .header("Expires", "0") + .send(indexHtml); } }); } diff --git a/frontend/scripts/replace-standalone-build-variable.sh b/frontend/scripts/replace-standalone-build-variable.sh index 5b1c4a27f7..c92397d934 100755 --- a/frontend/scripts/replace-standalone-build-variable.sh +++ b/frontend/scripts/replace-standalone-build-variable.sh @@ -10,16 +10,7 @@ fi echo "Replacing pre-baked value.." -# Escape special characters in REPLACEMENT for sed to avoid syntax errors -ESCAPED_REPLACEMENT=$(printf '%s\n' "$REPLACEMENT" | sed 's/[\/&]/\\&/g') - -# Replace in JS files in assets directory find assets -type f -name "*.js" | while read file; do - sed -i "s|$ORIGINAL|$ESCAPED_REPLACEMENT|g" "$file" + sed -i "s|$ORIGINAL|$REPLACEMENT|g" "$file" done - -# Replace in index.html (for asset references) -if [ -f "index.html" ]; then - sed -i "s|$ORIGINAL|$ESCAPED_REPLACEMENT|g" "index.html" -fi diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index f847676dba..56fd3e1831 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -29,14 +29,7 @@ export default defineConfig(({ mode }) => { "0.0.1" ).replaceAll(".", "-"); - // CDN HOST for static assets in /assets/* only. - // Docker: Set CDN_HOST env var at runtime (placeholder replaced at container startup). - // Direct build: Use --build-arg CDN_HOST=https://... or VITE_CDN_HOST env var. - // Default: Empty = same-origin asset loading. - const cdnHost = env.VITE_CDN_HOST || ""; - return { - base: "/", server: { allowedHosts, host: true, @@ -60,12 +53,12 @@ export default defineConfig(({ mode }) => { } }, experimental: { - // Only apply CDN HOST to files in /assets/* directory - renderBuiltUrl(filename) { - if (filename.startsWith("assets/") && cdnHost) { - return `${cdnHost}/${filename}`; + renderBuiltUrl(filename, { hostType }) { + if (hostType === "js") { + return { runtime: `window.__toCdnUrl(${JSON.stringify(filename)})` }; } - return `/${filename}`; + + return { relative: true }; } }, plugins: [ diff --git a/standalone-entrypoint.sh b/standalone-entrypoint.sh index 6ede9a0b88..7aa8712ef4 100755 --- a/standalone-entrypoint.sh +++ b/standalone-entrypoint.sh @@ -2,14 +2,4 @@ update-ca-certificates -if [ -d "/backend/frontend-build/assets" ]; then - cd /backend/frontend-build || { echo "ERROR: Failed to cd to frontend-build"; exit 1; } - - if ! /backend/scripts/replace-standalone-build-variable.sh "__INFISICAL_CDN_HOST__" "${CDN_HOST:-}"; then - echo "WARNING: CDN HOST replacement failed, assets may not load correctly" - fi - - cd /backend || { echo "ERROR: Failed to cd to backend"; exit 1; } -fi - exec node --enable-source-maps dist/main.mjs