How to Set Up LunaTV with Redis: Complete Configuration Guide

Set the NEXT_PUBLIC_STORAGE_TYPE environment variable to redis and provide a valid REDIS_URL connection string to enable high-performance Redis storage for user data in LunaTV.

LunaTV, the open-source media platform maintained by MoonTechLab, implements a pluggable storage architecture that supports Redis as a high-performance backend for user-specific data. When configured correctly, LunaTV stores play records, favorites, and skip configurations in Redis rather than the default filesystem storage. This configuration leverages the implementations found in src/lib/redis-base.db.ts and src/lib/redis.db.ts to provide fast read/write access and cross-device synchronization capabilities.

Configuration Environment Variables

LunaTV recognizes Redis as a storage backend through two critical environment variables. The application reads these at runtime to instantiate the correct storage driver.

  • NEXT_PUBLIC_STORAGE_TYPE: Must be set to the string "redis" to trigger the Redis storage implementation in src/lib/db.ts.
  • REDIS_URL: The connection string passed to the Redis client (e.g., redis://localhost:6379 or redis://moontv-redis:6379 when using Docker).

In src/lib/db.ts, the storage factory checks the storageType variable and instantiates RedisStorage when the value matches "redis":

// src/lib/db.ts (excerpt)
const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE;
if (storageType === 'redis') {
  // Creates a RedisStorage instance
}

Redis Client Architecture

The LunaTV codebase separates Redis connectivity into two layers to handle connection management and storage operations distinctly.

Connection Factory (redis-base.db.ts)

The createRedisClient function in src/lib/redis-base.db.ts constructs a singleton Redis client using the REDIS_URL environment variable. This implementation caches the client instance on a global symbol to prevent multiple connections during hot reloading in development. The factory configures automatic reconnection strategies and registers event listeners for error and ready states to ensure connection resilience.

Storage Implementation (redis.db.ts)

The RedisStorage class defined in src/lib/redis.db.ts extends the base client functionality to implement the IStorage interface. This class exposes methods including getPlayRecord, setPlayRecord, and deletePlayRecord, forwarding all operations to the Redis client established by the base factory. When NEXT_PUBLIC_STORAGE_TYPE=redis, the application uses this class to persist user data.

The official development configuration provides a containerized Redis instance with persistent storage. The docker-compose.dev.yml file defines both the LunaTV core application and a dedicated Redis service.


# docker-compose.dev.yml

services:
  moontv-core:
    environment:
      - NEXT_PUBLIC_STORAGE_TYPE=redis
      - REDIS_URL=redis://moontv-redis:6379
  moontv-redis:
    image: redis:7-alpine
    container_name: lunatv-redis
    command: redis-server --appendonly yes
    volumes:
      - ./data:/data

To deploy LunaTV with Redis using Docker:

  1. Clone the repository:

    git clone https://github.com/MoonTechLab/LunaTV.git && cd LunaTV
  2. Start the services:

    docker compose -f docker-compose.dev.yml up -d
  3. Verify connectivity:

    docker exec -it lunatv-redis redis-cli ping
    # Expected output: PONG
    
  4. Access the web interface at http://localhost:3000.

Manual Setup Without Docker

For local development or existing Redis infrastructure, configure the environment variables before starting the Node.js application:

export NEXT_PUBLIC_STORAGE_TYPE=redis
export REDIS_URL=redis://127.0.0.1:6379
npm run dev

Ensure your local Redis instance is running and accessible at the specified REDIS_URL. The createRedisClient function will handle connection establishment and error recovery automatically.

Using the Storage API

Once configured, the storage interface operates identically regardless of the backend implementation. Import the database singleton from @/lib/db to interact with user data:

import { db } from '@/lib/db';

// Save playback progress for user "alice"
await db.setPlayRecord('alice', 'movie:123', {
  episode: 1,
  position: 120,        // Seconds watched
  total: 3600,
  updatedAt: Date.now(),
});

// Retrieve resume position
const record = await db.getPlayRecord('alice', 'movie:123');
console.log('Resume at', record?.position);

All methods return Promises and handle serialization internally through the Redis storage layer.

Data Persistence Considerations

The Docker Compose configuration mounts a volume at ./data:/data to persist Redis append-only files (AOF) across container restarts. Without this volume mount, Redis stores data in memory only, and all user records—including play history and favorites—will be lost when the container stops or restarts. The official README warns specifically about this data loss risk when running Redis without persistent storage enabled.

For production deployments, ensure the REDIS_URL points to a Redis instance with proper persistence configuration (AOF or RDB snapshots) and backup strategies in place.

Summary

  • Set NEXT_PUBLIC_STORAGE_TYPE=redis to enable Redis storage in LunaTV.
  • Provide a valid REDIS_URL connection string to src/lib/redis.db.ts.
  • Use docker-compose.dev.yml for containerized deployment with automatic persistence via volume mounting.
  • The RedisStorage class in src/lib/redis.db.ts implements the standard IStorage interface for seamless API compatibility.
  • Always configure Redis persistence (append-only files or snapshots) to prevent data loss on container restarts.

Frequently Asked Questions

What happens if I don't set the REDIS_URL environment variable?

The createRedisClient function in src/lib/redis-base.db.ts attempts to connect using the REDIS_URL variable. If undefined, the Redis client initialization will fail, causing the LunaTV application to throw connection errors during startup when NEXT_PUBLIC_STORAGE_TYPE is set to redis.

Does LunaTV support Redis Sentinel or Cluster modes?

The current implementation in src/lib/redis-base.db.ts creates a single-instance Redis client using createClient from the Redis SDK. For Sentinel or Cluster configurations, you would need to modify the client factory to use the appropriate connection options, as the base implementation focuses on single-node connections.

How do I migrate existing data from filesystem storage to Redis?

LunaTV does not provide an automated migration tool in the current codebase. To migrate, you would need to write a custom script that reads existing records from the filesystem storage implementation and writes them to Redis using the setPlayRecord, setFavorites, and related methods exposed by the db singleton.

Is Redis data encrypted at rest in the Docker setup?

The default Docker Compose configuration uses the standard Redis Alpine image without encryption configuration. Data persistence relies on the host filesystem's encryption capabilities. For encryption at rest, configure Redis with TLS or use an encrypted volume mount, as the base client in src/lib/redis-base.db.ts supports TLS connections via the REDIS_URL protocol (rediss://).

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →