mirror of
https://gitlab.com/vyla-entertainment/documentation.git
synced 2026-11-14 22:47:26 -05:00
huge rewrite
This commit is contained in:
@@ -1,121 +1,194 @@
|
||||
# Self-host Stream API
|
||||
# Self-Hosting Stream API
|
||||
|
||||
<p class="page-description">Deploy the optional Stream API when your clients need an HTTP/SSE layer.</p>
|
||||
<p class="page-description">Complete production self-hosting guide for Stream API: Docker, Node.js systemd, PM2, and Nginx reverse proxy configuration with SSE streaming support.</p>
|
||||
|
||||
## Overview
|
||||
|
||||
Stream API is a **self-hosted Node.js** application that you run on infrastructure you control. It does not provide a public hosted instance. The service runs as a Node.js process, uses in-memory caching, and can fork workers through Node's built-in `cluster` module. No database is required by the service itself.
|
||||
Stream API is designed to be completely self-hostable on any Linux virtual private server (VPS), home server, or Docker container environment. Running your own instance gives you private access, eliminates shared IP rate limits, and allows you to tune worker concurrency to your hardware.
|
||||
|
||||
:::callout-warning
|
||||
Stream API is self-hosted only. There is no public Vyla streaming endpoint. You only need it when your architecture requires an HTTP/SSE layer; Node.js applications can use [Vyla SDK](/sdk) directly.
|
||||
:::
|
||||
---
|
||||
|
||||
## Requirements
|
||||
## Environment Variables
|
||||
|
||||
- Node.js 18 or later
|
||||
- A TMDB API key if you want title validation and metadata lookups
|
||||
Configure your environment variables via a `.env` file in the project root:
|
||||
|
||||
## Environment variables
|
||||
| Variable | Required | Default | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `PORT` | Optional | `7860` | HTTP port on which the server binds. |
|
||||
| `TMDB_API_KEY` | **Recommended** | `""` | The Movie Database v3 API key. Required for scrapers that resolve metadata via IMDb ID or episode titles. |
|
||||
| `WORKER_COUNT` | Optional | `os.cpus().length` | Number of worker processes to fork in cluster mode. |
|
||||
| `ENABLE_DEBUG_ROUTE` | Optional | `false` | Enables deep diagnostic traces at `/debug/:source`. Keep `false` in production. |
|
||||
| `GA_MEASUREMENT_ID` | Optional | `""` | Google Analytics 4 Measurement ID for private usage telemetry. |
|
||||
| `GA_API_SECRET` | Optional | `""` | Google Analytics 4 Measurement Protocol API Secret. |
|
||||
| `FALLBACK_BASE` | Optional | `""` | Secondary Stream API instance URL used for failover redirects. |
|
||||
| `IS_HF` | Optional | `false` | Enables HuggingFace Spaces compatibility constraints. |
|
||||
|
||||
Create a `.env` file in the project root:
|
||||
---
|
||||
|
||||
## Deployment Option 1: Docker (Recommended)
|
||||
|
||||
### 1. Dockerfile
|
||||
Create a `Dockerfile` in the project directory:
|
||||
|
||||
```dockerfile
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install native dependencies required for TLS and encryption
|
||||
RUN apk add --no-cache python3 make g++
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci --omit=dev
|
||||
|
||||
COPY . .
|
||||
|
||||
ENV PORT=7860
|
||||
EXPOSE 7860
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
```
|
||||
|
||||
### 2. Docker Compose
|
||||
Create a `docker-compose.yml` file:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
stream-api:
|
||||
build: .
|
||||
container_name: vyla-stream-api
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "127.0.0.1:7860:7860"
|
||||
environment:
|
||||
- PORT=7860
|
||||
- TMDB_API_KEY=your_tmdb_api_key_here
|
||||
- WORKER_COUNT=4
|
||||
- ENABLE_DEBUG_ROUTE=false
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
```
|
||||
|
||||
Start the container in detached mode:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Deployment Option 2: Direct Node.js & Systemd
|
||||
|
||||
### 1. Installation
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://gitlab.com/vyla-entertainment/stream-api.git /opt/stream-api
|
||||
cd /opt/stream-api
|
||||
|
||||
# Install dependencies
|
||||
npm ci --omit=dev
|
||||
```
|
||||
|
||||
### 2. Create Systemd Service
|
||||
Create `/etc/systemd/system/stream-api.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Vyla Stream API Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/opt/stream-api
|
||||
ExecStart=/usr/bin/node /opt/stream-api/server.js
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=NODE_ENV=production
|
||||
Environment=PORT=7860
|
||||
Environment=TMDB_API_KEY=your_tmdb_api_key_here
|
||||
Environment=WORKER_COUNT=4
|
||||
|
||||
# Security Hardening
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=full
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Enable and start the service:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now stream-api
|
||||
sudo systemctl status stream-api
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reverse Proxy: Nginx Configuration
|
||||
|
||||
Because Stream API utilizes **Server-Sent Events (SSE)** and large **HLS video streams**, your reverse proxy must disable proxy buffering. Standard buffering will delay SSE events until the buffer fills, breaking progressive playback.
|
||||
|
||||
Create an Nginx configuration at `/etc/nginx/sites-available/stream-api.conf`:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name stream-api.yourdomain.com;
|
||||
|
||||
# Maximum upload size for DB syncs
|
||||
client_max_body_size 20M;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:7860;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
# Mandatory for Server-Sent Events (SSE)
|
||||
proxy_set_header Connection '';
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
chunked_transfer_encoding off;
|
||||
|
||||
# Keep-Alive & Timeouts for long media streams
|
||||
proxy_read_timeout 90s;
|
||||
proxy_send_timeout 90s;
|
||||
|
||||
# Forward Client Identifiers for Geo-Token Verification
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
listen 80;
|
||||
}
|
||||
```
|
||||
|
||||
Enable the configuration and obtain a free SSL certificate via Certbot:
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/stream-api.conf /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
|
||||
# Install Let's Encrypt SSL
|
||||
sudo certbot --nginx -d stream-api.yourdomain.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verifying Your Deployment
|
||||
|
||||
Once deployed, verify the installation by testing the `/health` endpoint:
|
||||
|
||||
```bash
|
||||
TMDB_API_KEY=
|
||||
PORT=7860
|
||||
WORKER_COUNT=1
|
||||
ENABLE_DEBUG_ROUTE=false
|
||||
PROXY_STREAMS=false
|
||||
PROXY_URL=
|
||||
|
||||
GA_MEASUREMENT_ID=
|
||||
GA_API_SECRET=
|
||||
curl -i https://stream-api.yourdomain.com/health
|
||||
```
|
||||
|
||||
<div class="card">
|
||||
<div class="card-title">Variable reference</div>
|
||||
<div class="card-body">
|
||||
|
||||
| Variable | Required | Description |
|
||||
| --- | --- | --- |
|
||||
| `TMDB_API_KEY` | Yes | Enables TMDB-based ID validation, metadata lookups, and anime detection. Some sources will not work without it. |
|
||||
| `GA_MEASUREMENT_ID` / `GA_API_SECRET` | No | Enables Google Analytics event reporting. Leave blank to disable. |
|
||||
| `PORT` | No | Port the server listens on. Defaults to `7860`. |
|
||||
| `WORKER_COUNT` | No | Number of cluster workers to fork. Defaults to `1` locally. |
|
||||
| `ENABLE_DEBUG_ROUTE` | No | Set to `true` to enable `/api/debug/:id`. Keep this `false` in production - it exposes upstream request/response headers and raw source output. |
|
||||
| `PROXY_STREAMS` | No | Set to `true` to route stream playback through your own server's `/api` proxy endpoint instead of direct URLs. |
|
||||
| `PROXY_URL` | No | An external proxy base URL to use instead of the built-in `/api` proxy. Only used if `PROXY_STREAMS` is enabled. |
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## Installing and running
|
||||
|
||||
```bash
|
||||
git clone https://gitlab.com/vyla-entertainment/stream-api
|
||||
cd stream-api
|
||||
npm install
|
||||
node server.js
|
||||
```
|
||||
|
||||
The server listens on:
|
||||
|
||||
```
|
||||
http://localhost:7860
|
||||
```
|
||||
|
||||
Visit `/health` to confirm it is running and check which sources are currently reachable from your host.
|
||||
|
||||
## Running with multiple workers
|
||||
|
||||
Setting `WORKER_COUNT` above `1` forks additional worker processes via `cluster`.
|
||||
|
||||
The primary process holds a shared in-memory cache (capped at 1500 entries, pruned every 30 seconds) and relays cache reads/writes between workers over IPC, allowing cached stream results to be shared rather than duplicated.
|
||||
|
||||
```bash
|
||||
WORKER_COUNT=4
|
||||
node server.js
|
||||
```
|
||||
|
||||
Each worker independently loads source modules and handles outbound requests. Only shared cache operations and concurrency limits are coordinated through the primary process.
|
||||
|
||||
## Network considerations
|
||||
|
||||
Several sources are documented in `config.js` as blocked on datacenter IPs. This commonly affects cloud hosting providers and VPS environments.
|
||||
|
||||
If a source's `getStream` consistently returns nothing from your server but works from a residential connection, the cause is usually upstream blocking based on IP reputation. For the best experience, run Vyla API on a residential connection or use a residential proxy.
|
||||
|
||||
When running on a local desktop environment, you should have minimal issues with source availability since you're using a residential IP address.
|
||||
|
||||
## Reverse proxy / TLS
|
||||
|
||||
The server runs over plain HTTP. For public deployments, place it behind a reverse proxy such as Caddy, Nginx, or Cloudflare Tunnel to terminate TLS and forward requests to the configured `PORT`.
|
||||
|
||||
CORS is already configured at the application layer with:
|
||||
|
||||
```
|
||||
Access-Control-Allow-Origin: *
|
||||
```
|
||||
|
||||
No additional CORS configuration is required on the proxy.
|
||||
|
||||
## Verifying your deployment
|
||||
|
||||
Run these checks in order:
|
||||
|
||||
1. `GET /health`
|
||||
|
||||
Confirms the process is running and reports per-source reachability from your host.
|
||||
|
||||
2. `GET /api/test/155?source=vidrock`
|
||||
|
||||
Runs a real source resolution using a known TMDB movie ID and returns whether the source succeeded.
|
||||
|
||||
3. `GET /api/debug/155?source=vidrock`
|
||||
|
||||
Only available when `ENABLE_DEBUG_ROUTE=true`.
|
||||
|
||||
Returns request traces, headers, and raw candidate URLs for debugging source failures.
|
||||
|
||||
:::callout-warning
|
||||
Leave `ENABLE_DEBUG_ROUTE` disabled on public deployments. The debug route exposes upstream request information and raw stream URLs, which can leak internal details.
|
||||
:::
|
||||
You should receive an HTTP 200 (or 207) with JSON detailing the cluster status, cache count, and source probe results.
|
||||
|
||||
Reference in New Issue
Block a user