mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-13 04:26:16 -08:00
fix(docker): supervise self-hosted runtime processes
This commit is contained in:
1 parent
23a1330a14
commit
6afaa04a95
4 files changed
+55
-16
No files matched your search
+14
-12
@@ -43,12 +43,12 @@ before it creates `PwaService`.
|
||||
These variables are supported by the Docker image. The compose file sets the
|
||||
safe local defaults shown below.
|
||||
|
||||
| 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. Multiple origins can be comma-separated. |
|
||||
| `PORT` | `3000` | Internal Express backend port. nginx proxy config is rendered from the template to match it at startup. |
|
||||
| `IPTVNATOR_PROXY_ALLOW_PRIVATE_NETWORKS` | `0` | Set to `1` or `true` only for trusted local/LAN deployments that intentionally proxy private network IPTV or mock endpoints. |
|
||||
| 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. Multiple origins can be comma-separated. |
|
||||
| `PORT` | `3000` | Internal Express backend port. nginx proxy config is rendered from the template to match it at startup. |
|
||||
| `IPTVNATOR_PROXY_ALLOW_PRIVATE_NETWORKS` | `0` | Set to `1` or `true` only for trusted local/LAN deployments that intentionally proxy private network IPTV or mock endpoints. |
|
||||
| `NODE_EXTRA_CA_CERTS` | unset | Optional Node.js CA bundle path for providers using private certificate authorities. Mount the CA file into the container and set this path. |
|
||||
|
||||
The web backend proxy accepts only `http` and `https` provider URLs. The PWA
|
||||
@@ -64,18 +64,20 @@ enabled and pass the CA bundle to Node:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
iptvnator:
|
||||
volumes:
|
||||
- ./ca.pem:/etc/ssl/private/provider-ca.pem:ro
|
||||
environment:
|
||||
NODE_EXTRA_CA_CERTS: /etc/ssl/private/provider-ca.pem
|
||||
iptvnator:
|
||||
volumes:
|
||||
- ./ca.pem:/etc/ssl/private/provider-ca.pem:ro
|
||||
environment:
|
||||
NODE_EXTRA_CA_CERTS: /etc/ssl/private/provider-ca.pem
|
||||
```
|
||||
|
||||
The entrypoint renders the nginx config from `docker/nginx.conf`, starts the
|
||||
backend, waits for `/health`, and only then starts nginx. The nginx config
|
||||
serves the PWA with SPA fallback, avoids caching `assets/app-config.js`, and
|
||||
proxies `/api/*` to the internal backend. The Dockerfile and compose file both
|
||||
define a health check against `/api/health`.
|
||||
define a health check against `/api/health`. If nginx or the backend exits
|
||||
after startup, the entrypoint exits the container so Docker Compose can apply
|
||||
the `restart: unless-stopped` policy.
|
||||
|
||||
## Local Validation
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ services:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "4333:80"
|
||||
environment:
|
||||
|
||||
@@ -33,13 +33,24 @@ cleanup() {
|
||||
|
||||
if [ -n "${NGINX_PID:-}" ]; then
|
||||
kill "$NGINX_PID" 2>/dev/null || true
|
||||
wait "$NGINX_PID" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if [ -n "${BACKEND_PID:-}" ]; then
|
||||
kill "$BACKEND_PID" 2>/dev/null || true
|
||||
wait "$BACKEND_PID" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
process_is_running() {
|
||||
if [ ! -r "/proc/$1/stat" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
state="$(awk '{ print $3 }' "/proc/$1/stat" 2>/dev/null || true)"
|
||||
[ -n "$state" ] && [ "$state" != "Z" ]
|
||||
}
|
||||
|
||||
trap cleanup INT TERM EXIT
|
||||
|
||||
backend_ready=0
|
||||
@@ -50,9 +61,12 @@ for _ in $(seq 1 30); do
|
||||
break
|
||||
fi
|
||||
|
||||
if ! kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||
if ! process_is_running "$BACKEND_PID"; then
|
||||
set +e
|
||||
wait "$BACKEND_PID"
|
||||
exit $?
|
||||
BACKEND_STATUS=$?
|
||||
set -e
|
||||
exit "$BACKEND_STATUS"
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
@@ -66,4 +80,24 @@ fi
|
||||
nginx -g 'daemon off;' &
|
||||
NGINX_PID=$!
|
||||
|
||||
wait "$NGINX_PID"
|
||||
while :; do
|
||||
if ! process_is_running "$BACKEND_PID"; then
|
||||
set +e
|
||||
wait "$BACKEND_PID"
|
||||
EXIT_STATUS=$?
|
||||
set -e
|
||||
echo "IPTVnator web backend exited with status ${EXIT_STATUS}."
|
||||
exit "$EXIT_STATUS"
|
||||
fi
|
||||
|
||||
if ! process_is_running "$NGINX_PID"; then
|
||||
set +e
|
||||
wait "$NGINX_PID"
|
||||
EXIT_STATUS=$?
|
||||
set -e
|
||||
echo "nginx exited with status ${EXIT_STATUS}."
|
||||
exit "$EXIT_STATUS"
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
done
|
||||
@@ -109,7 +109,9 @@ The Docker image has two stages:
|
||||
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.
|
||||
backend, waits for `/health`, and then starts nginx. If either process exits
|
||||
after startup, the entrypoint exits the container so the compose restart
|
||||
policy can recover the service.
|
||||
|
||||
Default runtime values:
|
||||
|
||||
|
||||
Reference in new issue
Block a user