feat: update environment configuration and derive public URLs
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Modified .env.example to include PUBLIC_HOST and SECURE variables for better environment management. - Updated Dockerfile to pass PUBLIC_HOST and SECURE as build arguments and set them as environment variables. - Enhanced next.config.mjs to derive public-facing URLs based on PUBLIC_HOST and SECURE, improving flexibility for different deployment environments.
This commit is contained in:
parent
d6d18f911b
commit
ce364dbdb4
27
.env.example
27
.env.example
@ -1,29 +1,26 @@
|
||||
# =============================================================================
|
||||
# Public suite URL — edit PUBLIC_HOST + SECURE when switching domain
|
||||
# =============================================================================
|
||||
# Hostname only (no scheme). Keep in sync with ulti-backend/.env PUBLIC_HOST.
|
||||
PUBLIC_HOST=localhost
|
||||
# "s" → https/wss (Cloudflare tunnel, prod) ; empty → http/ws (local nginx :80)
|
||||
SECURE=
|
||||
|
||||
# API backend — URL relative : Next.js proxy vers nginx (:80), pas de CORS en dev
|
||||
NEXT_PUBLIC_API_URL=/api/v1
|
||||
NEXT_PUBLIC_WS_URL=ws://localhost/ws
|
||||
# Cible du proxy Next (optionnel, défaut 127.0.0.1:80)
|
||||
# Sert aussi aux appels OIDC serveur (discovery/token) — Docker: http://nginx
|
||||
# ULTI_PROXY_ORIGIN=http://127.0.0.1:80
|
||||
|
||||
# OIDC Authentik (blueprints deploy/authentik dans ulti-backend)
|
||||
NEXT_PUBLIC_OIDC_ISSUER=http://localhost/auth/application/o/ulti/
|
||||
NEXT_PUBLIC_OIDC_CLIENT_ID=ulti-backend
|
||||
# URL publique affichée dans les redirects OIDC (navigateur) — utiliser localhost, pas 0.0.0.0
|
||||
# URL publique navigateur (suite nginx) — pas :3004 si tu passes par http://localhost/mail
|
||||
NEXT_PUBLIC_APP_URL=http://localhost
|
||||
# Cookies session Secure (auto: true seulement si NEXT_PUBLIC_APP_URL est https://)
|
||||
# Cookies session Secure (auto: true si NEXT_PUBLIC_APP_URL dérivé en https://)
|
||||
# COOKIE_SECURE=false
|
||||
|
||||
# Secret serveur uniquement — doit matcher ULTID_OIDC_CLIENT_SECRET / blueprint
|
||||
OIDC_CLIENT_SECRET=changeme
|
||||
|
||||
# OnlyOffice editor (UltiDrive — tableurs/présentations)
|
||||
NEXT_PUBLIC_ONLYOFFICE_URL=http://localhost/office
|
||||
# Rich text editor (TipTap + Hocuspocus — docs texte)
|
||||
NEXT_PUBLIC_HOCUSPOCUS_URL=ws://localhost/collab
|
||||
# UltiAI (chemin proxy OpenWebUI — même origine)
|
||||
NEXT_PUBLIC_AI_PUBLIC_PATH=/ai
|
||||
# Origine UltiSpace par défaut (picker serveur apps Tauri mobiles)
|
||||
# NEXT_PUBLIC_ULTISPACE_ORIGIN=https://dev.ultispace.fr
|
||||
# Dev Next.js (:3000) : charger l'iframe depuis nginx (:80) pour cookies session + proxy OpenWebUI
|
||||
NEXT_PUBLIC_AI_ORIGIN=http://localhost
|
||||
|
||||
# NEXT_PUBLIC_APP_URL, WS_URL, OIDC_ISSUER, ONLYOFFICE_URL, HOCUSPOCUS_URL,
|
||||
# AI_ORIGIN, ULTISPACE_ORIGIN — dérivés dans next.config.mjs depuis PUBLIC_HOST + SECURE.
|
||||
|
||||
@ -12,6 +12,10 @@ FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
ARG PUBLIC_HOST=localhost
|
||||
ARG SECURE=
|
||||
ENV PUBLIC_HOST=$PUBLIC_HOST
|
||||
ENV SECURE=$SECURE
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
RUN pnpm run build
|
||||
|
||||
|
||||
@ -10,22 +10,48 @@ const projectRoot = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const ultiProxyOrigin = process.env.ULTI_PROXY_ORIGIN ?? "http://127.0.0.1"
|
||||
|
||||
/** "s" for https/wss when SECURE=s (or true/1). */
|
||||
function suiteSecureSuffix() {
|
||||
const secure = process.env.SECURE?.trim().toLowerCase()
|
||||
if (secure === "s" || secure === "true" || secure === "1") return "s"
|
||||
return ""
|
||||
}
|
||||
|
||||
/** Derive browser-facing NEXT_PUBLIC_* URLs from PUBLIC_HOST + SECURE. */
|
||||
function suitePublicEnv() {
|
||||
const host = (
|
||||
process.env.PUBLIC_HOST ??
|
||||
process.env.DOMAIN ??
|
||||
"localhost"
|
||||
).trim()
|
||||
const s = suiteSecureSuffix()
|
||||
const origin = `http${s}://${host}`
|
||||
return {
|
||||
NEXT_PUBLIC_APP_URL: origin,
|
||||
NEXT_PUBLIC_WS_URL: `ws${s}://${host}/ws`,
|
||||
NEXT_PUBLIC_OIDC_ISSUER: `${origin}/auth/application/o/ulti/`,
|
||||
NEXT_PUBLIC_ONLYOFFICE_URL: `${origin}/office`,
|
||||
NEXT_PUBLIC_HOCUSPOCUS_URL: `ws${s}://${host}/collab/`,
|
||||
NEXT_PUBLIC_AI_ORIGIN: origin,
|
||||
NEXT_PUBLIC_ULTISPACE_ORIGIN: origin,
|
||||
}
|
||||
}
|
||||
|
||||
/** Hostnames allowed to load /_next/* in dev (tunnel, LAN, public dev domain). */
|
||||
function allowedDevOrigins() {
|
||||
const hosts = new Set([
|
||||
"127.0.0.1",
|
||||
"localhost",
|
||||
"192.168.0.20",
|
||||
"100.120.4.66",
|
||||
"dev.ultispace.fr",
|
||||
"dev.ultimail.fr",
|
||||
])
|
||||
const appUrl = process.env.NEXT_PUBLIC_APP_URL?.trim()
|
||||
if (appUrl) {
|
||||
const hosts = new Set(["127.0.0.1", "localhost"])
|
||||
const publicHost = (
|
||||
process.env.PUBLIC_HOST ??
|
||||
process.env.DOMAIN ??
|
||||
""
|
||||
).trim()
|
||||
if (publicHost) hosts.add(publicHost)
|
||||
const derived = suitePublicEnv().NEXT_PUBLIC_APP_URL
|
||||
if (derived) {
|
||||
try {
|
||||
hosts.add(new URL(appUrl).hostname)
|
||||
hosts.add(new URL(derived).hostname)
|
||||
} catch {
|
||||
/* ignore invalid NEXT_PUBLIC_APP_URL */
|
||||
/* ignore invalid origin */
|
||||
}
|
||||
}
|
||||
return [...hosts]
|
||||
@ -46,6 +72,7 @@ const mobilePageExtensions = ["tsx", "ts", "jsx", "js"]
|
||||
const baseConfig = {
|
||||
outputFileTracingRoot: projectRoot,
|
||||
allowedDevOrigins: allowedDevOrigins(),
|
||||
env: suitePublicEnv(),
|
||||
typescript: {
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user