Files
documentation/self-hosting/index.html

280 lines
13 KiB
HTML

<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Self-host Stream API — Vyla</title>
<meta name="description" content="Deploy the optional Stream API when your clients need an HTTP/SSE layer." />
<meta name="keywords"
content="self-hosting, Stream API deployment, Node.js deployment, HTTP API, SSE, server setup, infrastructure" />
<link rel="canonical" href="https://vyla.cc/self-hosting.html" />
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website" />
<meta property="og:url" content="https://vyla.cc/self-hosting.html" />
<meta property="og:title" content="Self-host Stream API — Vyla" />
<meta property="og:description" content="Deploy the optional Stream API when your clients need an HTTP/SSE layer." />
<meta property="og:image" content="https://vyla.cc/assets/images/thumbnail.png" />
<meta property="og:site_name" content="Vyla" />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:url" content="https://vyla.cc/self-hosting.html" />
<meta property="twitter:title" content="Self-host Stream API — Vyla" />
<meta property="twitter:description"
content="Deploy the optional Stream API when your clients need an HTTP/SSE layer." />
<meta property="twitter:image" content="https://vyla.cc/assets/images/thumbnail.png" />
<meta property="twitter:site" content="@vylaentertainment" />
<!-- Additional SEO -->
<meta name="robots" content="index, follow" />
<meta name="author" content="Vyla" />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/assets/base.css" />
<link rel="stylesheet" href="/assets/highlight.css" />
<link rel="stylesheet" href="/assets/mintlify-overrides.css" />
<!-- JSON-LD Structured Data -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Self-host Stream API",
"description": "Deploy the optional Stream API when your clients need an HTTP/SSE layer.",
"url": "https://vyla.cc/self-hosting.html",
"applicationCategory": "MultimediaApplication",
"operatingSystem": "Windows, macOS, Linux, Android, Android TV",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
}
}
</script>
</head>
<body>
<div id="banner">
<span>Vyla is self-hosted. Run Vyla Home, embed the SDK, or deploy Stream API on infrastructure you control. Rights
holders can request source removal — <a href="/misc/dmca">DMCA policy</a>.</span>
<button id="banner-close" onclick="dismissBanner()" aria-label="Dismiss">✕</button>
</div>
<header id="navbar">
<div class="nav-top">
<a class="brand" href="/"><img src="/assets/images/logo.png" alt="Vyla" id="brand-logo" loading="lazy"
fetchpriority="low"></a>
<button id="search-trigger" type="button" onclick="openSearch()" aria-label="Search"></button>
<div class="links">
<button id="theme-toggle" type="button" onclick="toggleThemeMenu(event)" aria-label="Theme"></button>
</div>
</div>
<nav class="tabs">
<a class="tab-link" href="/">Vyla</a>
<a class="tab-link" href="/sdk">SDK</a>
<a class="tab-link active" href="/stream-api/overview">Stream API</a>
<a class="tab-link" href="/guides/integrations">Resources</a>
<a class="tab-link" href="/misc/credit">Misc</a>
</nav>
</header>
<div id="layout">
<nav id="sidebar">
<div class="group">
<p class="group-title">Overview</p>
<ul>
<li><a class="" href="/stream-api/overview">Overview</a></li>
</ul>
</div>
<div class="group">
<p class="group-title">Reference</p>
<ul>
<li><a class="" href="/stream-api/paths">Paths</a></li>
<li><a class="" href="/stream-api/media-data">Media Data</a></li>
<li><a class="" href="/stream-api/operations">Operations</a></li>
</ul>
</div>
<div class="group">
<p class="group-title">Deployment</p>
<ul>
<li><a class="active" href="/self-hosting">Self Hosting</a></li>
</ul>
</div>
</nav>
<div id="content-col">
<main class="prose">
<h1>Self-host Stream API</h1>
<p class="page-description">Deploy the optional Stream API when your clients need an HTTP/SSE layer.</p>
<h2 id="overview">Overview</h2>
<p>Stream API is a <strong>self-hosted Node.js</strong> 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 <code>cluster</code> module. No database is required by the
service itself.</p>
<div class="callout callout-warning">
<div class="callout-content">
<p>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 <a href="/sdk">Vyla SDK</a>
directly.</p>
</div>
</div>
<h2 id="requirements">Requirements</h2>
<ul>
<li>Node.js 18 or later</li>
<li>A TMDB API key if you want title validation and metadata lookups</li>
</ul>
<h2 id="environment-variables">Environment variables</h2>
<p>Create a <code>.env</code> file in the project root:</p>
<pre><code class="hljs language-bash">TMDB_API_KEY=
PORT=7860
WORKER_COUNT=1
ENABLE_DEBUG_ROUTE=<span class="hljs-literal">false</span>
PROXY_STREAMS=<span class="hljs-literal">false</span>
PROXY_URL=
<span class="hljs-comment"># Optional telemetry configuration</span>
GA_MEASUREMENT_ID=
GA_API_SECRET=
</code></pre>
<div class="card">
<div class="card-title">Variable reference</div>
<div class="card-body">
<table>
<thead>
<tr>
<th>Variable</th>
<th>Required</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>TMDB_API_KEY</code></td>
<td>Yes</td>
<td>Enables TMDB-based ID validation, metadata lookups, and anime detection. Some sources will not
work without it.</td>
</tr>
<tr>
<td><code>GA_MEASUREMENT_ID</code> / <code>GA_API_SECRET</code></td>
<td>No</td>
<td>Enables Google Analytics event reporting. Leave blank to disable.</td>
</tr>
<tr>
<td><code>PORT</code></td>
<td>No</td>
<td>Port the server listens on. Defaults to <code>7860</code>.</td>
</tr>
<tr>
<td><code>WORKER_COUNT</code></td>
<td>No</td>
<td>Number of cluster workers to fork. Defaults to <code>1</code> locally.</td>
</tr>
<tr>
<td><code>ENABLE_DEBUG_ROUTE</code></td>
<td>No</td>
<td>Set to <code>true</code> to enable <code>/api/debug/:id</code>. Keep this <code>false</code> in
production — it exposes upstream request/response headers and raw source output.</td>
</tr>
<tr>
<td><code>PROXY_STREAMS</code></td>
<td>No</td>
<td>Set to <code>true</code> to route stream playback through your own server's <code>/api</code>
proxy endpoint instead of direct URLs.</td>
</tr>
<tr>
<td><code>PROXY_URL</code></td>
<td>No</td>
<td>An external proxy base URL to use instead of the built-in <code>/api</code> proxy. Only used if
<code>PROXY_STREAMS</code> is enabled.
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h2 id="installing-and-running">Installing and running</h2>
<pre><code class="hljs language-bash">git <span class="hljs-built_in">clone</span> https://gitlab.com/vyla-entertainment/stream-api
<span class="hljs-built_in">cd</span> stream-api
npm install
node server.js
</code></pre>
<p>The server listens on:</p>
<pre><code>http://localhost:7860
</code></pre>
<p>Visit <code>/health</code> to confirm it is running and check which sources are currently reachable from your
host.</p>
<h2 id="running-with-multiple-workers">Running with multiple workers</h2>
<p>Setting <code>WORKER_COUNT</code> above <code>1</code> forks additional worker processes via
<code>cluster</code>.
</p>
<p>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.</p>
<pre><code class="hljs language-bash">WORKER_COUNT=4
node server.js
</code></pre>
<p>Each worker independently loads source modules and handles outbound requests. Only shared cache operations
and concurrency limits are coordinated through the primary process.</p>
<h2 id="network-considerations">Network considerations</h2>
<p>Several sources are documented in <code>config.js</code> as blocked on datacenter IPs. This commonly affects
cloud hosting providers and VPS environments.</p>
<p>If a source's <code>getStream</code> 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.</p>
<p>When running on a local desktop environment, you should have minimal issues with source availability since
you're using a residential IP address.</p>
<h2 id="reverse-proxy--tls">Reverse proxy / TLS</h2>
<p>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 <code>PORT</code>.</p>
<p>CORS is already configured at the application layer with:</p>
<pre><code>Access-Control-Allow-Origin: *
</code></pre>
<p>No additional CORS configuration is required on the proxy.</p>
<h2 id="verifying-your-deployment">Verifying your deployment</h2>
<p>Run these checks in order:</p>
<ol>
<li>
<p><code>GET /health</code></p>
<p>Confirms the process is running and reports per-source reachability from your host.</p>
</li>
<li>
<p><code>GET /api/test/155?source=vidrock</code></p>
<p>Runs a real source resolution using a known TMDB movie ID and returns whether the source succeeded.</p>
</li>
<li>
<p><code>GET /api/debug/155?source=vidrock</code></p>
<p>Only available when <code>ENABLE_DEBUG_ROUTE=true</code>.</p>
<p>Returns request traces, headers, and raw candidate URLs for debugging source failures.</p>
</li>
</ol>
<div class="callout callout-warning">
<div class="callout-content">
<p>Leave <code>ENABLE_DEBUG_ROUTE</code> disabled on public deployments. The debug route exposes upstream
request information and raw stream URLs, which can leak internal details.</p>
</div>
</div>
</main>
<aside id="toc">
<p class="toc-title">On this page</p>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#requirements">Requirements</a></li>
<li><a href="#environment-variables">Environment variables</a></li>
<li><a href="#installing-and-running">Installing and running</a></li>
<li><a href="#running-with-multiple-workers">Running with multiple workers</a></li>
<li><a href="#network-considerations">Network considerations</a></li>
<li><a href="#reverse-proxy--tls">Reverse proxy / TLS</a></li>
<li><a href="#verifying-your-deployment">Verifying your deployment</a></li>
</ul>
</aside>
</div>
</div>
<footer id="site-footer">
<a href="https://discord.gg/5eqRhKeywG" target="_blank" rel="noopener">Discord</a>
<a href="https://gitlab.com/vyla-entertainment/" target="_blank" rel="noopener">GitLab</a>
</footer>
<script src="/assets/app.js"></script>
</body>
</html>