How to Configure Upstash for LunaTV Deployments: Complete Setup Guide
Set NEXT_PUBLIC_STORAGE_TYPE=upstash and provide UPSTASH_URL and UPSTASH_TOKEN environment variables to enable managed Redis storage for user data, favorites, and playback history in LunaTV.
LunaTV is an open-source media platform that supports multiple storage backends for persisting runtime data. Configuring Upstash provides a fully managed, serverless Redis experience ideal for cloud-native deployments where you want to avoid maintaining your own Redis infrastructure.
Prerequisites for Upstash Integration
Before deploying, ensure you have:
- An active Upstash account with a Redis database provisioned
- The HTTPS endpoint URL (
UPSTASH_URL) and authentication token (UPSTASH_TOKEN) from your Upstash console - LunaTV source code that includes the Upstash storage implementation found in
src/lib/upstash.db.ts
Required Environment Variables
LunaTV reads three specific environment variables at runtime to initialize the Upstash connection. According to the source code in src/lib/db.ts, the factory function checks process.env.NEXT_PUBLIC_STORAGE_TYPE and instantiates UpstashRedisStorage when the value is upstash.
Configure these variables in your deployment environment:
NEXT_PUBLIC_STORAGE_TYPE– Must be set toupstash(defaults tolocalstorageif omitted).UPSTASH_URL– The HTTPS endpoint provided by Upstash (e.g.,https://clever-duck-12345.upstash.io).UPSTASH_TOKEN– The read-write token for your Upstash Redis database.
If either UPSTASH_URL or UPSTASH_TOKEN is undefined, the constructor in src/lib/upstash.db.ts throws an error, preventing the application from starting with invalid credentials.
Docker Compose Configuration
For containerized deployments using Docker Compose, define the environment variables as follows:
services:
lunatv:
image: ghcr.io/moontechlab/lunatv:latest
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_STORAGE_TYPE=upstash
- UPSTASH_URL=https://your-endpoint.upstash.io
- UPSTASH_TOKEN=your-upstash-token
- USERNAME=admin
- PASSWORD=your_secure_password
How the Upstash Storage Layer Works
Understanding the implementation details in src/lib/upstash.db.ts helps optimize your deployment and troubleshoot issues.
Storage Selection Logic
The application uses a factory pattern in src/lib/db.ts to select storage backends. The middleware (src/middleware.ts) and database layer read process.env.NEXT_PUBLIC_STORAGE_TYPE at runtime. When set to upstash, the factory creates an instance of UpstashRedisStorage rather than the default local storage or standard Redis implementations.
Singleton Client Pattern
UpstashRedisStorage obtains a singleton Redis client via getUpstashRedisClient(). This function constructs the client using your UPSTASH_URL and UPSTASH_TOKEN, ensuring connection reuse across requests and preventing connection pool exhaustion in serverless environments.
Automatic Retry Mechanism
All Redis operations wrap in a withRetry() utility defined in src/lib/upstash.db.ts. This wrapper automatically retries transient connection failures (such as ECONNREFUSED) up to three times before throwing, providing resilience against temporary network interruptions.
Data Model and Hash Keys
Upstash stores each user's data in separate Hash keys following the pattern u:{user}:{type}. The storage layer manages:
u:{user}:pr– Playback records and watch historyu:{user}:fav– Favorites and bookmarksu:{user}:search– Search query history
The UpstashRedisStorage class provides methods for CRUD operations on these hashes, password hashing, admin configuration, and data migration utilities.
Programmatic Usage Examples
For custom scripts or server-side operations, import the storage class directly:
import { UpstashRedisStorage } from '@/lib/upstash.db';
// The client automatically reads UPSTASH_URL and UPSTASH_TOKEN from process.env
const storage = new UpstashRedisStorage();
// Add a favorite movie for user "alice"
await storage.setFavorite('alice', 'movie:12345', {
id: '12345',
title: 'Inception',
type: 'movie',
ts: Date.now(),
});
To manually switch storage modes in code, use the factory pattern from src/lib/db.ts:
export function createStorage(): IStorage {
const type = process.env.NEXT_PUBLIC_STORAGE_TYPE as
| 'redis' | 'kvrocks' | 'upstash' | undefined;
if (type === 'upstash') return new UpstashRedisStorage();
// Additional branches for other storage types...
}
Summary
- Set
NEXT_PUBLIC_STORAGE_TYPE=upstashto activate the Upstash storage backend in LunaTV. - Provide
UPSTASH_URLandUPSTASH_TOKENenvironment variables; missing values trigger startup errors. - The
UpstashRedisStorageclass insrc/lib/upstash.db.tsmanages connection pooling, automatic retries, and data serialization. - User data persists in Upstash Redis hashes using keys formatted as
u:{user}:{data_type}. - The middleware in
src/middleware.tsreads the storage type early in the request pipeline to ensure consistent backend selection.
Frequently Asked Questions
What happens if UPSTASH_URL or UPSTASH_TOKEN is missing?
The application throws a configuration error during initialization. The constructor in src/lib/upstash.db.ts validates these environment variables and prevents startup to avoid runtime failures in production.
Can I migrate existing data from local storage to Upstash?
LunaTV includes data migration utilities within the storage layer, but you must manually export data from your current backend and import it into Upstash. The application does not automatically migrate existing local storage data to Redis on startup.
Does the Upstash integration support Redis pub/sub features?
The current implementation focuses on Hash-based persistence for user records, favorites, and playback history. While the underlying Upstash client supports pub/sub capabilities, the core UpstashRedisStorage class does not implement real-time messaging features.
How does the retry mechanism handle network failures?
All Redis operations wrap in withRetry(), which catches transient errors such as ECONNREFUSED and retries the operation up to three times. This ensures resilience against temporary network interruptions common in serverless and edge computing environments.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →