Environment Variables

Complete reference for every .env variable supported by KissKH Video Player

Updated May 5, 2026
OtakuThemes Team

Overview

All configuration is done through environment variables, either in a .env file at the project root or via your hosting platform's environment variable UI (cPanel, Railway, Render, etc.).

Copy .env.example to .env to get started:

cp .env.example .env

Below is a complete reference for every supported variable.


Server

PORT

RequiredNo
Default3000

The TCP port the server listens on.

PORT=3000
cPanel / Passenger

Do not set PORT on Passenger-based hosting. Passenger manages the port automatically.


KissKH API

KISSKH_BASE_URL

RequiredNo
Defaulthttps://kisskh.co

The base URL for the KissKH website and API. Only change this if KissKH moves to a new domain and you need to point the server at it.

KISSKH_BASE_URL=https://kisskh.co

KISSKH_CACHE_TTL

RequiredNo
Default900 (15 minutes)

How long, in seconds, to cache episode video URL responses from the KissKH API. Increasing this reduces API calls but means video URL changes take longer to propagate.

KISSKH_CACHE_TTL=900

KISSKH_SUB_CACHE_TTL

RequiredNo
Default3600 (1 hour)

How long, in seconds, to cache subtitle list responses from the KissKH API. Subtitles change less frequently than video URLs, so the default is longer.

KISSKH_SUB_CACHE_TTL=3600

KISSKH_HOST_CACHE_TTL

RequiredNo
Default900 (15 minutes)

How long, in seconds, to cache the result of the internal probe that decides which proxy host to use for a given video URL.

KISSKH_HOST_CACHE_TTL=900

Proxy & CDN

PROXY_URL

RequiredNo
Default(unset — uses the current server)

When set, all /vid/ and /sub/ proxy URLs will point to this external server instead of the current one. Use this to offload video bandwidth to a separate Node.js instance running the same server.js code — for example, a second VPS or a cheaper bandwidth region.

PROXY_URL=https://proxy.example.com

When unset, the current server handles all proxying itself.


Security

URL_SECRET

RequiredNo (but strongly recommended in production)
Default(unset)

A random secret string used to AES-encrypt the proxy URL path segments (/vid/ and /sub/). When set, the encoded URLs are unguessable — a viewer cannot reverse-engineer the original CDN URL from the iframe source.

When unset, the server falls back to plain base64 encoding, which is easily decoded.

Set this to any long random string:

URL_SECRET=change-me-to-a-long-random-string
Security Recommendation

Always set URL_SECRET in production. Without it, anyone who inspects the iframe's network requests can decode the CDN URLs and bypass your server entirely.

ALLOWED_ORIGIN

RequiredNo
Default(unset — allows the current serving domain only)

A comma-separated list of origins allowed to make requests to the /vid/ and /sub/ proxy endpoints. By default, the proxy only accepts requests from the same domain the server is running on.

Set this only if your player page and your proxy server are on different domains:

ALLOWED_ORIGIN=https://your-site.com,https://another-site.com

IFRAME_ALLOWED_ORIGIN

RequiredNo
Default(unset — all domains can embed the player)

A comma-separated list of origins allowed to embed the /kisskh/{id} player page in an <iframe>. By default, any domain can embed the player.

Set this to restrict which websites can embed your player:

IFRAME_ALLOWED_ORIGIN=https://your-site.com,https://another-site.com
Embed Security

When IFRAME_ALLOWED_ORIGIN is set, any attempt to embed the player from an unlisted domain will receive a 403 error page instead of the player. Direct browser access (no iframe) is always blocked regardless of this setting.


Admin Panel

ADMIN_PASSWORD

RequiredNo (admin panel is disabled until this is set)
Default(unset — admin panel disabled)

The password for the admin panel at /admin. The admin panel is completely disabled until you set this. Choose a strong password.

ADMIN_PASSWORD=your-secure-password

ADMIN_USERNAME

RequiredNo
Defaultadmin

The username for the admin panel login.

ADMIN_USERNAME=admin

ADMIN_SECRET

RequiredNo
DefaultFalls back to URL_SECRET, then kisskh-admin

A secret used to sign admin session cookies. You do not need to set this separately if you have already set URL_SECRET — the server uses URL_SECRET as the session signing key when ADMIN_SECRET is not explicitly provided.

ADMIN_SECRET=another-random-secret

Cache (Redis)

REDIS_URL

RequiredNo
Default(unset — in-memory cache only)

Connection URL for an optional Redis (or Valkey) instance. When set, the server uses Redis as a shared cache in addition to the local in-memory cache. This is useful for multi-instance deployments where you want cache to be shared across servers.

Supports both plain and TLS connections:

# Plain Redis
REDIS_URL=redis://localhost:6379/0
 
# Redis with password
REDIS_URL=redis://:mypassword@localhost:6379/0
 
# Redis with TLS (e.g. Upstash)
REDIS_URL=rediss://user:password@host:6380/0

When REDIS_URL is not set, the server runs with in-memory caching only, which is perfectly fine for single-instance deployments.

REDIS_TIMEOUT_MS

RequiredNo
Default500

Timeout in milliseconds for Redis commands. If Redis is slow or unreachable, the server falls back to the in-memory cache rather than blocking.

REDIS_TIMEOUT_MS=500

CACHE_MAX_ENTRIES

RequiredNo
Default500

Maximum number of entries in the in-memory LRU cache. Older entries are evicted when the limit is reached. Increase this on servers with more RAM to reduce KissKH API calls.

CACHE_MAX_ENTRIES=500

CACHE_MEMORY_TTL

RequiredNo
Default60 (seconds)

When Redis is configured, cache entries fetched from Redis are also stored in the local in-memory cache for this many seconds to avoid repeated Redis round-trips.

CACHE_MEMORY_TTL=60

Minimal Production .env

Here is a minimal .env suitable for a production single-server deployment:

PORT=3000
 
ADMIN_PASSWORD=your-secure-password
URL_SECRET=replace-with-a-long-random-string
 
KISSKH_CACHE_TTL=900
KISSKH_SUB_CACHE_TTL=3600

Add IFRAME_ALLOWED_ORIGIN if you want to lock down which sites can embed the player.