docs: document PWA self-hosted runtime

This commit is contained in:
4gray committed 2026-05-15 11:20:55 +02:00
1 parent 8f81db0d2d
commit 9d0ded1905
4 files changed
+172 -10

No files matched your search

+10
View File
@@ -18,6 +18,16 @@ This file provides guidance to coding agents working in this repository.
- See `docs/architecture/nx-workspace-boundaries.md` for the current Nx tag and alias policy.
- Repository-specific skills are committed under `.codex/skills/`. If an external agent does not support skills, treat those files as concise ownership docs.
## PWA / Self-hosted Web
- The browser self-hosted backend lives in `apps/web-backend`. Do not rely on the historical external `4gray/iptvnator-backend` container for the default Docker flow unless the task explicitly asks to re-sync missing behavior from that repository.
- The Angular PWA resolves its backend through `window.__IPTVNATOR_CONFIG__.BACKEND_URL`, read by `apps/web/src/app/services/runtime-config.ts`. The placeholder file is `apps/web/src/assets/app-config.js`; Docker rewrites the built copy at container startup.
- Keep `assets/app-config.js` out of Angular service worker hashing in `ngsw-config.json`. Runtime rewrites after `web:pwa` must not invalidate `ngsw.json`.
- For PWA output checks, run `pnpm nx build web --configuration=pwa --skip-nx-cache` and verify `dist/apps/web/ngsw-worker.js` plus `dist/apps/web/ngsw.json` exist. If Nx serves stale build metadata after project config changes, run `pnpm nx reset`.
- `web:serve-static` should serve `dist/apps/web` from `web:build:pwa`; do not point it back at the old `dist/apps/web/browser` layout.
- The unified Docker image builds `web:pwa` and `web-backend`, serves static files through nginx, and proxies `/api/*` to the internal Express backend. Keep `BACKEND_URL=/api` for the bundled self-hosted setup.
- Validate Xtream and Stalker self-hosted changes with the mock servers and `pnpm nx run web-e2e:e2e -- --project=chromium --grep @self-hosted`.
## Documentation After Changes
- After implementing a meaningful change, agents must assess whether canonical repo docs need updates before considering the task complete.
+16 -1
View File
@@ -55,7 +55,7 @@ The application is a cross-platform, open-source project built with Electron and
- Polish
- Custom "User Agent" header configuration for playlists
- Light and Dark themes
- Docker version available for self-hosting
- Docker image available for self-hosting the PWA and web backend together
## Screenshots:
@@ -79,6 +79,21 @@ The application is a cross-platform, open-source project built with Electron and
_Note: First version of the application which was developed as a PWA is available in an extra git branch._
## Self-hosted PWA
The Docker setup builds the Angular PWA and the monorepo web backend into one
image. The backend handles remote M3U/XMLTV parsing plus Xtream and Stalker
proxy requests under `/api`, so a separate `4gray/iptvnator-backend` container
is not required for the default self-hosted flow.
```bash
docker compose -f docker/docker-compose.yml up --build
```
The application is available at <http://localhost:4333>. See
[`docker/README.md`](./docker/README.md) for environment variables and build
details.
## Download
Download the latest version of the application for macOS, Windows, and Linux from the [release page](https://github.com/4gray/iptvnator/releases).
+48 -9
View File
@@ -1,16 +1,55 @@
# Self-hosted version of IPTVnator
# Self-hosted IPTVnator
You can deploy and run the PWA version of IPTVnator on your own machine with `docker-compose` using the following command:
The self-hosted image contains both pieces required for the browser PWA:
$ cd docker
$ docker-compose up -d
- Angular PWA static files served by nginx
- The monorepo `web-backend` Express app proxied under `/api`
This command will launch the frontend and backend applications. By default, the application will be available at: http://localhost:4333/. The ports can be configured in the `docker-compose.yml` file.
The historical standalone `4gray/iptvnator-backend` image is no longer needed
for the default Docker deployment.
## Build frontend
## Run With Docker Compose
$ docker build -t 4gray/iptvnator -f docker/Dockerfile .
```bash
docker compose -f docker/docker-compose.yml up --build -d
```
## Build backend
By default the app is available at <http://localhost:4333>.
You can find the backend app with all instructions in a separate GitHub repository - https://github.com/4gray/iptvnator-backend
## Build The Image
```bash
docker build -t 4gray/iptvnator -f docker/Dockerfile .
```
The image build runs:
```bash
pnpm nx build web --configuration=pwa
pnpm nx build web-backend
```
## Runtime Configuration
The container writes `/usr/share/nginx/html/assets/app-config.js` on startup.
That file sets `window.__IPTVNATOR_CONFIG__.BACKEND_URL`, which the PWA reads
before it creates `PwaService`.
| Variable | Default | Purpose |
| ------------- | ----------------------- | ------------------------------------------------------------------------------------------------ |
| `BACKEND_URL` | `/api` | Browser-facing backend URL used by the PWA. Keep `/api` for the bundled nginx proxy. |
| `CLIENT_URL` | `http://localhost:4333` | Allowed browser origin for backend CORS. Use the public URL when hosting behind a reverse proxy. |
| `PORT` | `3000` | Internal Express backend port. nginx proxy config is patched to match it at container startup. |
The nginx config serves the PWA with SPA fallback, avoids caching
`assets/app-config.js`, and proxies `/api/*` to the internal backend.
## Local Validation
```bash
pnpm nx test web-backend
pnpm nx build web --configuration=pwa --skip-nx-cache
pnpm nx build web-backend
pnpm nx run web-e2e:e2e -- --project=chromium --grep @self-hosted
docker compose -f docker/docker-compose.yml config
```
+98
View File
@@ -0,0 +1,98 @@
# PWA Self-hosted Architecture
This document describes the browser PWA and self-hosted Docker path.
## Ownership
- `apps/web` owns the Angular browser UI and PWA service worker configuration.
- `apps/web-backend` owns the browser-only backend proxy for remote playlist,
XMLTV, Xtream, and Stalker requests.
- `docker/` owns the production self-hosted image that bundles the PWA and
`web-backend` into one container.
The old external `4gray/iptvnator-backend` repository is not required for the
default self-hosted deployment. Sync behavior from that repository only when a
change intentionally restores or imports missing backend capabilities.
## Runtime Backend Configuration
The PWA reads `window.__IPTVNATOR_CONFIG__.BACKEND_URL` through
`apps/web/src/app/services/runtime-config.ts`. The static placeholder lives at
`apps/web/src/assets/app-config.js` and keeps hosted builds working without
Docker-specific values.
The Docker entrypoint rewrites `assets/app-config.js` at container startup.
`ngsw-config.json` explicitly excludes this file from Angular service worker
asset hashing so a runtime rewrite does not break cache validation.
## Service Worker Build
Use the PWA build configuration for browser deployments:
```bash
pnpm nx build web --configuration=pwa
```
The build must emit these files in `dist/apps/web`:
- `ngsw-worker.js`
- `ngsw.json`
- `safety-worker.js`
- `worker-basic.min.js`
`web:serve-static` serves `dist/apps/web` and builds with
`web:build:pwa`, so it exercises the same output layout as Docker. If Nx daemon
state returns stale service worker outputs while changing build options, run:
```bash
pnpm nx reset
pnpm nx build web --configuration=pwa --skip-nx-cache
```
## Web Backend
`apps/web-backend` exposes these routes:
- `GET /health`
- `GET /config.js`
- `GET /parse?url=<m3u-url>`
- `GET /parse-xml?url=<xmltv-url>`
- `GET /xtream?url=<server>&username=<u>&password=<p>&action=<action>`
- `GET /stalker?url=<portal.php>&macAddress=<mac>&action=<action>`
The PWA continues to use `PwaService`; only the backend base URL is resolved at
runtime. Electron routes remain owned by the Electron backend and preload
bridge.
## Docker Runtime
The Docker image has two stages:
1. Build stage installs dependencies and runs `web:pwa` plus `web-backend`.
2. Runtime stage uses `node:22-alpine` with nginx installed. nginx serves
`dist/apps/web` and proxies `/api/*` to the local Express backend.
Default runtime values:
- `BACKEND_URL=/api`
- `CLIENT_URL=http://localhost:4333`
- `PORT=3000`
When hosting behind another domain, set `CLIENT_URL` to the browser origin and
keep `BACKEND_URL=/api` unless the reverse proxy exposes the backend elsewhere.
## Validation
Use the narrow validation ladder for self-hosted changes:
```bash
pnpm nx test web-backend
pnpm nx test web --runTestsByPath apps/web/src/app/services/runtime-config.spec.ts
pnpm nx build web --configuration=pwa --skip-nx-cache
pnpm nx build web-backend
pnpm nx run web-e2e:e2e -- --project=chromium --grep @self-hosted
docker compose -f docker/docker-compose.yml config
```
Run `docker build -t iptvnator:self-hosted-test -f docker/Dockerfile .` when a
Docker daemon is available.