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
|
# API backend — URL relative : Next.js proxy vers nginx (:80), pas de CORS en dev
|
||||||
NEXT_PUBLIC_API_URL=/api/v1
|
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)
|
# Cible du proxy Next (optionnel, défaut 127.0.0.1:80)
|
||||||
# Sert aussi aux appels OIDC serveur (discovery/token) — Docker: http://nginx
|
# Sert aussi aux appels OIDC serveur (discovery/token) — Docker: http://nginx
|
||||||
# ULTI_PROXY_ORIGIN=http://127.0.0.1:80
|
# 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
|
NEXT_PUBLIC_OIDC_CLIENT_ID=ulti-backend
|
||||||
# URL publique affichée dans les redirects OIDC (navigateur) — utiliser localhost, pas 0.0.0.0
|
# Cookies session Secure (auto: true si NEXT_PUBLIC_APP_URL dérivé en https://)
|
||||||
# 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://)
|
|
||||||
# COOKIE_SECURE=false
|
# COOKIE_SECURE=false
|
||||||
|
|
||||||
# Secret serveur uniquement — doit matcher ULTID_OIDC_CLIENT_SECRET / blueprint
|
# Secret serveur uniquement — doit matcher ULTID_OIDC_CLIENT_SECRET / blueprint
|
||||||
OIDC_CLIENT_SECRET=changeme
|
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)
|
# UltiAI (chemin proxy OpenWebUI — même origine)
|
||||||
NEXT_PUBLIC_AI_PUBLIC_PATH=/ai
|
NEXT_PUBLIC_AI_PUBLIC_PATH=/ai
|
||||||
# Origine UltiSpace par défaut (picker serveur apps Tauri mobiles)
|
|
||||||
# NEXT_PUBLIC_ULTISPACE_ORIGIN=https://dev.ultispace.fr
|
# NEXT_PUBLIC_APP_URL, WS_URL, OIDC_ISSUER, ONLYOFFICE_URL, HOCUSPOCUS_URL,
|
||||||
# Dev Next.js (:3000) : charger l'iframe depuis nginx (:80) pour cookies session + proxy OpenWebUI
|
# AI_ORIGIN, ULTISPACE_ORIGIN — dérivés dans next.config.mjs depuis PUBLIC_HOST + SECURE.
|
||||||
NEXT_PUBLIC_AI_ORIGIN=http://localhost
|
|
||||||
|
|||||||
@ -12,6 +12,10 @@ FROM base AS builder
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
|
ARG PUBLIC_HOST=localhost
|
||||||
|
ARG SECURE=
|
||||||
|
ENV PUBLIC_HOST=$PUBLIC_HOST
|
||||||
|
ENV SECURE=$SECURE
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
RUN pnpm run build
|
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"
|
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). */
|
/** Hostnames allowed to load /_next/* in dev (tunnel, LAN, public dev domain). */
|
||||||
function allowedDevOrigins() {
|
function allowedDevOrigins() {
|
||||||
const hosts = new Set([
|
const hosts = new Set(["127.0.0.1", "localhost"])
|
||||||
"127.0.0.1",
|
const publicHost = (
|
||||||
"localhost",
|
process.env.PUBLIC_HOST ??
|
||||||
"192.168.0.20",
|
process.env.DOMAIN ??
|
||||||
"100.120.4.66",
|
""
|
||||||
"dev.ultispace.fr",
|
).trim()
|
||||||
"dev.ultimail.fr",
|
if (publicHost) hosts.add(publicHost)
|
||||||
])
|
const derived = suitePublicEnv().NEXT_PUBLIC_APP_URL
|
||||||
const appUrl = process.env.NEXT_PUBLIC_APP_URL?.trim()
|
if (derived) {
|
||||||
if (appUrl) {
|
|
||||||
try {
|
try {
|
||||||
hosts.add(new URL(appUrl).hostname)
|
hosts.add(new URL(derived).hostname)
|
||||||
} catch {
|
} catch {
|
||||||
/* ignore invalid NEXT_PUBLIC_APP_URL */
|
/* ignore invalid origin */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [...hosts]
|
return [...hosts]
|
||||||
@ -46,6 +72,7 @@ const mobilePageExtensions = ["tsx", "ts", "jsx", "js"]
|
|||||||
const baseConfig = {
|
const baseConfig = {
|
||||||
outputFileTracingRoot: projectRoot,
|
outputFileTracingRoot: projectRoot,
|
||||||
allowedDevOrigins: allowedDevOrigins(),
|
allowedDevOrigins: allowedDevOrigins(),
|
||||||
|
env: suitePublicEnv(),
|
||||||
typescript: {
|
typescript: {
|
||||||
ignoreBuildErrors: true,
|
ignoreBuildErrors: true,
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user