From cd5e0abe5309fde58a0895ab96c008961e88df8a Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Tue, 16 Jun 2026 02:11:13 +0530 Subject: [PATCH] refactor(docker): drop build-time NEXT_PUBLIC injection for runtime env --- docker/docker-compose.dev.yml | 11 ++-- docker/docker-compose.yml | 12 ++-- surfsense_web/Dockerfile | 17 ------ surfsense_web/docker-entrypoint.js | 98 ------------------------------ surfsense_web/docker-entrypoint.sh | 2 - 5 files changed, 9 insertions(+), 131 deletions(-) delete mode 100644 surfsense_web/docker-entrypoint.js diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 35effefc0..2435fcb0f 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -253,16 +253,15 @@ services: frontend: build: context: ../surfsense_web - args: - NEXT_PUBLIC_FASTAPI_BACKEND_URL: ${NEXT_PUBLIC_FASTAPI_BACKEND_URL:-http://localhost:8000} - NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE: ${NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE:-LOCAL} - NEXT_PUBLIC_ETL_SERVICE: ${NEXT_PUBLIC_ETL_SERVICE:-DOCLING} - NEXT_PUBLIC_ZERO_CACHE_URL: ${NEXT_PUBLIC_ZERO_CACHE_URL:-http://localhost:${ZERO_CACHE_PORT:-4848}} - NEXT_PUBLIC_DEPLOYMENT_MODE: ${NEXT_PUBLIC_DEPLOYMENT_MODE:-self-hosted} ports: - "${FRONTEND_PORT:-3000}:3000" env_file: - ../surfsense_web/.env + environment: + AUTH_TYPE: ${AUTH_TYPE:-LOCAL} + ETL_SERVICE: ${ETL_SERVICE:-DOCLING} + DEPLOYMENT_MODE: ${DEPLOYMENT_MODE:-self-hosted} + SURFSENSE_BACKEND_INTERNAL_URL: http://backend:8000 depends_on: backend: condition: service_healthy diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 342753ed3..3bb614c0c 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -285,14 +285,10 @@ services: expose: - "3000" environment: - NEXT_PUBLIC_FASTAPI_BACKEND_URL: ${NEXT_PUBLIC_FASTAPI_BACKEND_URL:-${SURFSENSE_PUBLIC_URL:-http://localhost:${LISTEN_HTTP_PORT:-3929}}} - NEXT_PUBLIC_ZERO_CACHE_URL: ${NEXT_PUBLIC_ZERO_CACHE_URL:-${SURFSENSE_PUBLIC_URL:-http://localhost:${LISTEN_HTTP_PORT:-3929}}/zero} - BACKEND_URL: ${BACKEND_URL:-${SURFSENSE_PUBLIC_URL:-http://localhost:${LISTEN_HTTP_PORT:-3929}}} - NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE: ${AUTH_TYPE:-LOCAL} - NEXT_PUBLIC_ETL_SERVICE: ${ETL_SERVICE:-DOCLING} - NEXT_PUBLIC_DEPLOYMENT_MODE: ${DEPLOYMENT_MODE:-self-hosted} - NEXT_PUBLIC_WHATSAPP_DISPLAY_PHONE_NUMBER: ${WHATSAPP_SHARED_DISPLAY_PHONE_NUMBER:-} - FASTAPI_BACKEND_INTERNAL_URL: ${FASTAPI_BACKEND_INTERNAL_URL:-http://backend:8000} + AUTH_TYPE: ${AUTH_TYPE:-LOCAL} + ETL_SERVICE: ${ETL_SERVICE:-DOCLING} + DEPLOYMENT_MODE: ${DEPLOYMENT_MODE:-self-hosted} + SURFSENSE_BACKEND_INTERNAL_URL: http://backend:8000 labels: - "com.centurylinklabs.watchtower.enable=true" depends_on: diff --git a/surfsense_web/Dockerfile b/surfsense_web/Dockerfile index d851cf045..48f389a6b 100644 --- a/surfsense_web/Dockerfile +++ b/surfsense_web/Dockerfile @@ -35,21 +35,6 @@ RUN apk add --no-cache git # Enable pnpm RUN corepack enable pnpm -# Build with placeholder values for NEXT_PUBLIC_* variables. -# These are replaced at container startup by docker-entrypoint.js -# with real values from the container's environment variables. -ARG NEXT_PUBLIC_FASTAPI_BACKEND_URL=__NEXT_PUBLIC_FASTAPI_BACKEND_URL__ -ARG NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=__NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE__ -ARG NEXT_PUBLIC_ETL_SERVICE=__NEXT_PUBLIC_ETL_SERVICE__ -ARG NEXT_PUBLIC_ZERO_CACHE_URL=__NEXT_PUBLIC_ZERO_CACHE_URL__ -ARG NEXT_PUBLIC_DEPLOYMENT_MODE=__NEXT_PUBLIC_DEPLOYMENT_MODE__ - -ENV NEXT_PUBLIC_FASTAPI_BACKEND_URL=$NEXT_PUBLIC_FASTAPI_BACKEND_URL -ENV NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=$NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE -ENV NEXT_PUBLIC_ETL_SERVICE=$NEXT_PUBLIC_ETL_SERVICE -ENV NEXT_PUBLIC_ZERO_CACHE_URL=$NEXT_PUBLIC_ZERO_CACHE_URL -ENV NEXT_PUBLIC_DEPLOYMENT_MODE=$NEXT_PUBLIC_DEPLOYMENT_MODE - COPY --from=deps /app/node_modules ./node_modules COPY . . @@ -78,8 +63,6 @@ COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone/app/ ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static -# Entrypoint scripts for runtime env var substitution -COPY --chown=nextjs:nodejs docker-entrypoint.js ./docker-entrypoint.js COPY --chown=nextjs:nodejs --chmod=755 docker-entrypoint.sh ./docker-entrypoint.sh USER nextjs diff --git a/surfsense_web/docker-entrypoint.js b/surfsense_web/docker-entrypoint.js deleted file mode 100644 index 1dc6883ed..000000000 --- a/surfsense_web/docker-entrypoint.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Runtime environment variable substitution for Next.js Docker images. - * - * Next.js inlines NEXT_PUBLIC_* values at build time. The Docker image is built - * with unique placeholder strings (e.g. __NEXT_PUBLIC_FASTAPI_BACKEND_URL__). - * This script replaces those placeholders with real values from the container's - * environment variables before the server starts. - * - * Runs once at container startup via docker-entrypoint.sh. - */ - -const fs = require("fs"); -const path = require("path"); - -function envValue(name, fallback, { allowEmpty = false } = {}) { - if (Object.hasOwn(process.env, name)) { - const value = process.env[name]; - if (allowEmpty || value) { - return value ?? ""; - } - } - return fallback; -} - -const replacements = [ - [ - "__NEXT_PUBLIC_FASTAPI_BACKEND_URL__", - envValue("NEXT_PUBLIC_FASTAPI_BACKEND_URL", "http://localhost:8000", { allowEmpty: true }), - ], - [ - "__NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE__", - envValue("NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE", "LOCAL"), - ], - ["__NEXT_PUBLIC_ETL_SERVICE__", envValue("NEXT_PUBLIC_ETL_SERVICE", "DOCLING")], - [ - "__NEXT_PUBLIC_ZERO_CACHE_URL__", - envValue("NEXT_PUBLIC_ZERO_CACHE_URL", "http://localhost:4848", { allowEmpty: true }), - ], - ["__NEXT_PUBLIC_DEPLOYMENT_MODE__", envValue("NEXT_PUBLIC_DEPLOYMENT_MODE", "self-hosted")], -]; - -let filesProcessed = 0; -let filesModified = 0; - -function walk(dir) { - let entries; - try { - entries = fs.readdirSync(dir, { withFileTypes: true }); - } catch { - return; - } - for (const entry of entries) { - const full = path.join(dir, entry.name); - if (entry.isDirectory()) { - walk(full); - } else if (entry.name.endsWith(".js")) { - filesProcessed++; - let content = fs.readFileSync(full, "utf8"); - let changed = false; - for (const [placeholder, value] of replacements) { - if (content.includes(placeholder)) { - content = content.replaceAll(placeholder, value); - changed = true; - } - } - if (changed) { - fs.writeFileSync(full, content); - filesModified++; - } - } - } -} - -console.log("[entrypoint] Replacing environment variable placeholders..."); -for (const [placeholder, value] of replacements) { - console.log(` ${placeholder} -> ${value}`); -} - -walk(path.join(__dirname, ".next")); - -const serverJs = path.join(__dirname, "server.js"); -if (fs.existsSync(serverJs)) { - let content = fs.readFileSync(serverJs, "utf8"); - let changed = false; - filesProcessed++; - for (const [placeholder, value] of replacements) { - if (content.includes(placeholder)) { - content = content.replaceAll(placeholder, value); - changed = true; - } - } - if (changed) { - fs.writeFileSync(serverJs, content); - filesModified++; - } -} - -console.log(`[entrypoint] Done. Scanned ${filesProcessed} files, modified ${filesModified}.`); diff --git a/surfsense_web/docker-entrypoint.sh b/surfsense_web/docker-entrypoint.sh index 7f4dfbf25..63f857ad3 100644 --- a/surfsense_web/docker-entrypoint.sh +++ b/surfsense_web/docker-entrypoint.sh @@ -1,6 +1,4 @@ #!/bin/sh set -e -node /app/docker-entrypoint.js - exec node server.js