mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-08 23:18:05 -05:00
refactor: remove CDN_HOST references from Dockerfiles and entrypoint, streamline asset loading configuration
This commit is contained in:
@@ -2,8 +2,6 @@ ARG POSTHOG_HOST=https://app.posthog.com
|
|||||||
ARG POSTHOG_API_KEY=posthog-api-key
|
ARG POSTHOG_API_KEY=posthog-api-key
|
||||||
ARG INTERCOM_ID=intercom-id
|
ARG INTERCOM_ID=intercom-id
|
||||||
ARG CAPTCHA_SITE_KEY=captcha-site-key
|
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
|
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
|
ENV VITE_INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
||||||
ARG CAPTCHA_SITE_KEY
|
ARG CAPTCHA_SITE_KEY
|
||||||
ENV VITE_CAPTCHA_SITE_KEY $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"
|
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 --from=frontend-runner /app ./backend/frontend-build
|
||||||
|
|
||||||
# Copy CDN HOST replacement script for runtime CDN HOST replacement
|
RUN chmod +x /backend/scripts/export-assets.sh
|
||||||
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
|
|
||||||
|
|
||||||
ARG INFISICAL_PLATFORM_VERSION
|
ARG INFISICAL_PLATFORM_VERSION
|
||||||
ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ ARG POSTHOG_HOST=https://app.posthog.com
|
|||||||
ARG POSTHOG_API_KEY=posthog-api-key
|
ARG POSTHOG_API_KEY=posthog-api-key
|
||||||
ARG INTERCOM_ID=intercom-id
|
ARG INTERCOM_ID=intercom-id
|
||||||
ARG CAPTCHA_SITE_KEY=captcha-site-key
|
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
|
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
|
ENV VITE_INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
||||||
ARG CAPTCHA_SITE_KEY
|
ARG CAPTCHA_SITE_KEY
|
||||||
ENV VITE_CAPTCHA_SITE_KEY $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"
|
ENV NODE_OPTIONS="--max-old-space-size=8192"
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
@@ -178,10 +174,7 @@ ENV CAPTCHA_SITE_KEY=$CAPTCHA_SITE_KEY
|
|||||||
COPY --from=backend-runner /app /backend
|
COPY --from=backend-runner /app /backend
|
||||||
COPY --from=frontend-runner /app ./backend/frontend-build
|
COPY --from=frontend-runner /app ./backend/frontend-build
|
||||||
|
|
||||||
# Copy CDN HOST replacement script for runtime CDN HOST replacement
|
RUN chmod +x /backend/scripts/export-assets.sh
|
||||||
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
|
|
||||||
|
|
||||||
ARG INFISICAL_PLATFORM_VERSION
|
ARG INFISICAL_PLATFORM_VERSION
|
||||||
ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
ENV INFISICAL_PLATFORM_VERSION $INFISICAL_PLATFORM_VERSION
|
||||||
|
|||||||
@@ -229,6 +229,7 @@ const envSchema = z
|
|||||||
CAPTCHA_SECRET: zpStr(z.string().optional()),
|
CAPTCHA_SECRET: zpStr(z.string().optional()),
|
||||||
CAPTCHA_SITE_KEY: zpStr(z.string().optional()),
|
CAPTCHA_SITE_KEY: zpStr(z.string().optional()),
|
||||||
INTERCOM_ID: zpStr(z.string().optional()),
|
INTERCOM_ID: zpStr(z.string().optional()),
|
||||||
|
CDN_HOST: zpStr(z.string().optional()),
|
||||||
|
|
||||||
// TELEMETRY
|
// TELEMETRY
|
||||||
OTEL_TELEMETRY_COLLECTION_ENABLED: zodStrBool.default("false"),
|
OTEL_TELEMETRY_COLLECTION_ENABLED: zodStrBool.default("false"),
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import fs from "node:fs";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
import staticServe from "@fastify/static";
|
import staticServe from "@fastify/static";
|
||||||
|
import RE2 from "re2";
|
||||||
|
|
||||||
import { getConfig, IS_PACKAGED } from "@app/lib/config/env";
|
import { getConfig, IS_PACKAGED } from "@app/lib/config/env";
|
||||||
|
|
||||||
@@ -15,6 +17,9 @@ export const registerServeUI = async (
|
|||||||
dir: string;
|
dir: string;
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
|
const appCfg = getConfig();
|
||||||
|
const cdnHost = appCfg.CDN_HOST || "";
|
||||||
|
|
||||||
// use this only for frontend runtime static non-sensitive configuration in standalone mode
|
// use this only for frontend runtime static non-sensitive configuration in standalone mode
|
||||||
// that app needs before loading like posthog dsn key
|
// that app needs before loading like posthog dsn key
|
||||||
// for most of the other usecase use server config
|
// for most of the other usecase use server config
|
||||||
@@ -25,15 +30,26 @@ export const registerServeUI = async (
|
|||||||
hide: true
|
hide: true
|
||||||
},
|
},
|
||||||
handler: (_req, res) => {
|
handler: (_req, res) => {
|
||||||
const appCfg = getConfig();
|
|
||||||
void res.type("application/javascript");
|
void res.type("application/javascript");
|
||||||
const config = {
|
const config = {
|
||||||
CAPTCHA_SITE_KEY: appCfg.CAPTCHA_SITE_KEY,
|
CAPTCHA_SITE_KEY: appCfg.CAPTCHA_SITE_KEY,
|
||||||
POSTHOG_API_KEY: appCfg.POSTHOG_PROJECT_API_KEY,
|
POSTHOG_API_KEY: appCfg.POSTHOG_PROJECT_API_KEY,
|
||||||
INTERCOM_ID: appCfg.INTERCOM_ID,
|
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);
|
return res.send(js);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -41,6 +57,23 @@ export const registerServeUI = async (
|
|||||||
if (standaloneMode) {
|
if (standaloneMode) {
|
||||||
const frontendName = IS_PACKAGED ? "frontend" : "frontend-build";
|
const frontendName = IS_PACKAGED ? "frontend" : "frontend-build";
|
||||||
const frontendPath = path.join(dir, frontendName);
|
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, {
|
await server.register(staticServe, {
|
||||||
root: frontendPath,
|
root: frontendPath,
|
||||||
wildcard: false,
|
wildcard: false,
|
||||||
@@ -60,12 +93,12 @@ export const registerServeUI = async (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return reply.sendFile("index.html", {
|
return reply
|
||||||
immutable: false,
|
.type("text/html")
|
||||||
maxAge: 0,
|
.header("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
lastModified: false,
|
.header("Pragma", "no-cache")
|
||||||
etag: false
|
.header("Expires", "0")
|
||||||
});
|
.send(indexHtml);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,16 +10,7 @@ fi
|
|||||||
|
|
||||||
echo "Replacing pre-baked value.."
|
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" |
|
find assets -type f -name "*.js" |
|
||||||
while read file; do
|
while read file; do
|
||||||
sed -i "s|$ORIGINAL|$ESCAPED_REPLACEMENT|g" "$file"
|
sed -i "s|$ORIGINAL|$REPLACEMENT|g" "$file"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Replace in index.html (for asset references)
|
|
||||||
if [ -f "index.html" ]; then
|
|
||||||
sed -i "s|$ORIGINAL|$ESCAPED_REPLACEMENT|g" "index.html"
|
|
||||||
fi
|
|
||||||
|
|||||||
@@ -29,14 +29,7 @@ export default defineConfig(({ mode }) => {
|
|||||||
"0.0.1"
|
"0.0.1"
|
||||||
).replaceAll(".", "-");
|
).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 {
|
return {
|
||||||
base: "/",
|
|
||||||
server: {
|
server: {
|
||||||
allowedHosts,
|
allowedHosts,
|
||||||
host: true,
|
host: true,
|
||||||
@@ -60,12 +53,12 @@ export default defineConfig(({ mode }) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
experimental: {
|
experimental: {
|
||||||
// Only apply CDN HOST to files in /assets/* directory
|
renderBuiltUrl(filename, { hostType }) {
|
||||||
renderBuiltUrl(filename) {
|
if (hostType === "js") {
|
||||||
if (filename.startsWith("assets/") && cdnHost) {
|
return { runtime: `window.__toCdnUrl(${JSON.stringify(filename)})` };
|
||||||
return `${cdnHost}/${filename}`;
|
|
||||||
}
|
}
|
||||||
return `/${filename}`;
|
|
||||||
|
return { relative: true };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
|||||||
@@ -2,14 +2,4 @@
|
|||||||
|
|
||||||
update-ca-certificates
|
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
|
exec node --enable-source-maps dist/main.mjs
|
||||||
|
|||||||
Reference in New Issue
Block a user