diff --git a/Dockerfile.web b/Dockerfile.web index 5e8987f22..d1f507c5b 100644 --- a/Dockerfile.web +++ b/Dockerfile.web @@ -37,8 +37,10 @@ RUN pnpm install --frozen-lockfile --offline # Set build-time env: tells Next.js rewrites to proxy API calls to the backend service ARG REMOTE_API_URL=http://backend:8080 ARG NEXT_PUBLIC_GOOGLE_CLIENT_ID +ARG NEXT_PUBLIC_WS_URL ENV REMOTE_API_URL=$REMOTE_API_URL ENV NEXT_PUBLIC_GOOGLE_CLIENT_ID=$NEXT_PUBLIC_GOOGLE_CLIENT_ID +ENV NEXT_PUBLIC_WS_URL=$NEXT_PUBLIC_WS_URL ENV STANDALONE=true # Build the web app (standalone output for minimal runtime) diff --git a/SELF_HOSTING_ADVANCED.md b/SELF_HOSTING_ADVANCED.md index f32df08d5..f33e459b5 100644 --- a/SELF_HOSTING_ADVANCED.md +++ b/SELF_HOSTING_ADVANCED.md @@ -218,6 +218,26 @@ NEXT_PUBLIC_API_URL=https://api.example.com NEXT_PUBLIC_WS_URL=wss://api.example.com/ws ``` +## LAN / Non-localhost Access + +By default, Multica works on `localhost`. If you access it from another machine on the LAN (e.g. `http://192.168.1.100:3000`), you need to tell the backend to accept that origin: + +```bash +# .env — replace with your server's LAN IP +FRONTEND_ORIGIN=http://192.168.1.100:3000 +CORS_ALLOWED_ORIGINS=http://192.168.1.100:3000 +``` + +Then rebuild: + +```bash +docker compose -f docker-compose.selfhost.yml up -d --build +``` + +The frontend automatically derives the WebSocket URL from the page address, so real-time features (chat streaming, live issue updates, notifications) work over LAN without extra configuration. + +> **Note:** If you need to override the WebSocket URL explicitly (e.g. when using a separate backend domain), set `NEXT_PUBLIC_WS_URL` in `.env` and rebuild the frontend image. + ## Health Check The backend exposes a health check endpoint: diff --git a/apps/web/components/web-providers.tsx b/apps/web/components/web-providers.tsx index 79557301f..f9820b8bc 100644 --- a/apps/web/components/web-providers.tsx +++ b/apps/web/components/web-providers.tsx @@ -22,12 +22,22 @@ function hasLegacyToken(): boolean { } } +// Derive WebSocket URL from the page origin so self-hosted / LAN deployments +// work without explicit NEXT_PUBLIC_WS_URL. The Next.js rewrite rule +// (/ws → backend) handles proxying. +function deriveWsUrl(): string | undefined { + if (process.env.NEXT_PUBLIC_WS_URL) return process.env.NEXT_PUBLIC_WS_URL; + if (typeof window === "undefined") return undefined; + const proto = window.location.protocol === "https:" ? "wss:" : "ws:"; + return `${proto}//${window.location.host}/ws`; +} + export function WebProviders({ children }: { children: React.ReactNode }) { const cookieAuth = !hasLegacyToken(); return (