mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 19:27:41 -08:00
docs(docker): restore self-hosted PWA compose flow
This commit is contained in:
1 parent
3096115e64
commit
23a1330a14
7 files changed
+377
-51
No files matched your search
@@ -0,0 +1,148 @@
|
||||
# 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,
|
||||
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
|
||||
|
||||
The current self-hosted PWA uses these `apps/web-backend` routes:
|
||||
|
||||
- `GET /health`
|
||||
- `GET /config.js`
|
||||
- `POST /provider-targets` with `{ "url": "<provider-url>" }`
|
||||
- `GET /parse?targetId=<id>`
|
||||
- `GET /xtream?targetId=<id>&username=<u>&password=<p>&action=<action>`
|
||||
- `GET /stalker?targetId=<id>&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.
|
||||
|
||||
EPG/XMLTV is not a supported self-hosted PWA capability yet. Do not document it
|
||||
as part of the Docker user flow or use it as the readiness signal for this path.
|
||||
|
||||
Provider URLs are registered before proxy calls so the proxy endpoints do not
|
||||
accept raw target URLs in query strings. Registration validates the target URL
|
||||
before any outbound request:
|
||||
|
||||
- only `http:` and `https:` provider URLs are accepted
|
||||
- URL credentials are rejected
|
||||
- loopback, private, link-local, and reserved network targets are blocked by
|
||||
default
|
||||
- `IPTVNATOR_PROXY_ALLOW_PRIVATE_NETWORKS=1` explicitly enables trusted
|
||||
local/LAN targets for development, mock servers, or private deployments
|
||||
|
||||
Do not disable TLS certificate validation in the backend proxy. For private
|
||||
certificate authorities, configure Node with `NODE_EXTRA_CA_CERTS`.
|
||||
|
||||
## PWA Portal User Data
|
||||
|
||||
Xtream favorites and recently viewed items use the browser-side
|
||||
`PwaXtreamDataSource` when Electron DB preload APIs are unavailable. The PWA
|
||||
stores this user activity in localStorage:
|
||||
|
||||
- `xtream-favorites`
|
||||
- `xtream-recent-items`
|
||||
|
||||
Entries should include a content snapshot when the item is added. Global
|
||||
collection routes and the dashboard can then restore titles, posters, content
|
||||
type, and category IDs after navigation or a page reload without relying on the
|
||||
Electron SQLite content table.
|
||||
|
||||
Shared collection services must not import `@iptvnator/portal/xtream/data-access`
|
||||
directly. Use `XTREAM_COLLECTION_DATA_SOURCE` from
|
||||
`@iptvnator/portal/shared/util` and bind it to `XTREAM_DATA_SOURCE` at the app
|
||||
provider boundary (`apps/web/src/app/app.config.ts`). This keeps
|
||||
`portal-shared-util` provider-neutral and avoids adding new Nx boundary cycles.
|
||||
|
||||
## 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.
|
||||
The entrypoint renders the nginx config from a `${PORT}` template, starts the
|
||||
backend, waits for `/health`, and then starts nginx.
|
||||
|
||||
Default runtime values:
|
||||
|
||||
- `BACKEND_URL=/api`
|
||||
- `CLIENT_URL=http://localhost:4333`
|
||||
- `PORT=3000`
|
||||
- `IPTVNATOR_PROXY_ALLOW_PRIVATE_NETWORKS=0`
|
||||
- `NODE_EXTRA_CA_CERTS` unset
|
||||
|
||||
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.
|
||||
Only set `IPTVNATOR_PROXY_ALLOW_PRIVATE_NETWORKS=1` when the self-hosted
|
||||
instance is restricted to trusted users and intentionally needs private network
|
||||
IPTV targets. For providers using private certificate authorities, mount the CA
|
||||
bundle into the container and set `NODE_EXTRA_CA_CERTS` to that mounted path.
|
||||
|
||||
## 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.
|
||||
|
||||
For manual Docker smoke testing, run the Xtream and Stalker mock servers plus a
|
||||
small M3U fixture, then verify in the browser that M3U, Xtream, and Stalker can
|
||||
add sources, play an item, toggle favorites, populate global favorites,
|
||||
populate recently viewed, and appear on the dashboard rails.
|
||||
Reference in new issue
Block a user