# How to Set Up LunaTV with Kvrocks: Docker & Cloud Deployment Guide

> Learn to set up LunaTV with Kvrocks using Docker Compose or Zeabur. Deploy Redis-compatible storage easily for your LunaTV core service. Get persistent storage now.

- Repository: [MoonTechLab/LunaTV](https://github.com/MoonTechLab/LunaTV)
- Tags: how-to-guide
- Published: 2026-09-09

---

**TLDR:** Set `NEXT_PUBLIC_STORAGE_TYPE=kvrocks` and `KVROCKS_URL=redis://host:6666`, then deploy the `apache/kvrocks` container alongside the LunaTV core service using Docker Compose or Zeabur for persistent, Redis-compatible storage.

LunaTV (MoonTechLab/LunaTV) is an open-source media management platform that supports multiple storage backends. When configured with **Kvrocks**—a Redis-compatible key-value store built on RocksDB—it provides durable, high-performance storage for user play records, favorites, and search history. This guide covers the complete setup process using Docker Compose and Zeabur cloud deployment.

## Understanding the Kvrocks Storage Architecture

LunaTV implements Kvrocks support through a layered architecture that extends base Redis functionality.

**Key Components**

- **`KvrocksStorage`** – Located in [`src/lib/kvrocks.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/kvrocks.db.ts), this class extends `BaseRedisStorage` to provide a concrete client for Kvrocks. It reads the `KVROCKS_URL` environment variable and registers a global client instance.

- **`BaseRedisStorage`** – Defined in [`src/lib/redis-base.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/redis-base.db.ts), this implements all storage operations including play records, favorites, user management, and data migrations. It includes built-in retry and reconnection logic for production reliability.

- **`DbManager`** – Found in [`src/lib/db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/db.ts), this factory class instantiates the appropriate storage implementation based on `NEXT_PUBLIC_STORAGE_TYPE`. When set to `kvrocks`, it returns a `KvrocksStorage` instance.

## Docker Compose Setup

This approach runs both LunaTV and Kvrocks in containers with persistent volume storage.

### Step 1: Create the Compose Configuration

Create a [`docker-compose.yml`](https://github.com/MoonTechLab/LunaTV/blob/main/docker-compose.yml) that defines the LunaTV core service and the Kvrocks backend:

```yaml
services:
  moontv-core:
    image: ghcr.io/moontechlab/lunatv:latest
    container_name: moontv-core
    restart: on-failure
    ports:
      - "3000:3000"
    environment:
      - USERNAME=admin
      - PASSWORD=admin_password
      - NEXT_PUBLIC_STORAGE_TYPE=kvrocks
      - KVROCKS_URL=redis://moontv-kvrocks:6666
    depends_on:
      - moontv-kvrocks
    networks:
      - moontv-network

  moontv-kvrocks:
    image: apache/kvrocks
    container_name: moontv-kvrocks
    restart: unless-stopped
    volumes:
      - kvrocks-data:/var/lib/kvrocks
    networks:
      - moontv-network

networks:
  moontv-network:
    driver: bridge

volumes:
  kvrocks-data:

```

**Critical configuration details:**
- The `KVROCKS_URL` uses the service name `moontv-kvrocks` as the hostname
- Kvrocks listens on port **6666** by default
- Data persists in the named volume `kvrocks-data`

### Step 2: Start the Services

Run the composition in detached mode:

```bash
docker compose up -d

```

The Kvrocks container initializes and persists data to `/var/lib/kvrocks`, while LunaTV connects automatically using the provided environment variables.

### Step 3: Verify Connectivity

Confirm the Kvrocks instance is responding:

```bash
docker exec -it moontv-kvrocks kvrocks-cli -h localhost -p 6666 ping

```

A successful response returns `PONG`. Access LunaTV at `http://localhost:3000` and log in with the credentials defined in the `USERNAME` and `PASSWORD` environment variables.

## Zeabur Cloud Deployment

For managed deployments, Zeabur provides a one-click setup equivalent to the Docker Compose configuration.

**Deployment steps:**

1. **Add Kvrocks Service** – Deploy the `apache/kvrocks` image on port `6666`.
2. **Add LunaTV Service** – Deploy `ghcr.io/moontechlab/lunatv:latest` on port `3000`.
3. **Configure Environment Variables** for the LunaTV service:
   ```env
   USERNAME=admin
   PASSWORD=your_secure_password
   NEXT_PUBLIC_STORAGE_TYPE=kvrocks
   KVROCKS_URL=redis://apachekvrocks:6666
   ```

   Replace `apachekvrocks` with the actual service name if customized.
4. **Deploy** and bind a custom domain if required.

The platform automatically handles networking between services, and LunaTV connects to Kvrocks on startup.

## Environment Variable Reference

| Variable | Required | Description |
|----------|----------|-------------|
| `NEXT_PUBLIC_STORAGE_TYPE` | Yes | Set to `kvrocks` to enable the Kvrocks storage driver. |
| `KVROCKS_URL` | Yes | Connection URL in format `redis://<host>:6666`. |
| `USERNAME` | Yes | Admin username for LunaTV authentication. |
| `PASSWORD` | Yes | Admin password for LunaTV authentication. |

## Programmatic Access for Custom Scripts

For administrative tasks or migrations outside the normal server lifecycle, instantiate the storage client directly:

```typescript
import { KvrocksStorage } from '@/src/lib/kvrocks.db';

// Ensure KVROCKS_URL is present in process.env
const kvrocks = new KvrocksStorage();

// Example: Add a favorite item for user "alice"
await kvrocks.setFavorite('alice', 'movie+12345', {
  title: 'Example Movie',
  url: 'https://example.com/movie/12345',
  poster: 'https://example.com/poster.jpg',
});

```

All storage methods—including `getPlayRecord`, `addSearchHistory`, and `deleteUser`—are inherited from `BaseRedisStorage` according to the implementation in [`src/lib/redis-base.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/redis-base.db.ts).

## Summary

- **LunaTV** uses the `KvrocksStorage` class in [`src/lib/kvrocks.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/kvrocks.db.ts) to connect to Kvrocks when `NEXT_PUBLIC_STORAGE_TYPE=kvrocks` is set.
- The storage driver requires the `KVROCKS_URL` environment variable pointing to a Kvrocks instance on port **6666**.
- **Docker Compose** deployments should use the `apache/kvrocks` image with a persistent volume for data durability.
- **Zeabur** offers a managed alternative with identical environment variable configuration.
- All data operations leverage `BaseRedisStorage` in [`src/lib/redis-base.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/redis-base.db.ts), providing retry logic and reconnection handling.

## Frequently Asked Questions

### What is the difference between KvrocksStorage and BaseRedisStorage?

`KvrocksStorage` is a thin wrapper in [`src/lib/kvrocks.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/kvrocks.db.ts) that extends `BaseRedisStorage` from [`src/lib/redis-base.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/redis-base.db.ts). While `KvrocksStorage` handles client initialization and global registration using `KVROCKS_URL`, `BaseRedisStorage` contains the actual implementation for all data operations like storing play records and managing favorites.

### Can I use a custom Kvrocks port instead of 6666?

Yes, but you must ensure the `KVROCKS_URL` environment variable reflects the custom port (e.g., `redis://host:6379`). However, the standard `apache/kvrocks` Docker image exposes port **6666** by default, so changing this requires mapping ports in your Docker Compose configuration or Kubernetes manifests.

### How does LunaTV handle connection failures to Kvrocks?

The `BaseRedisStorage` implementation includes automatic retry logic and reconnection handling. If the Kvrocks instance becomes unavailable, LunaTV will attempt to reconnect using exponential backoff rather than crashing, ensuring resilience during temporary network interruptions or Kvrock restarts.

### Is data migration supported when switching to Kvrocks?

According to the source code in [`src/lib/redis-base.db.ts`](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/redis-base.db.ts), the storage layer includes migration logic for data structure updates. However, migrating existing data from other storage types (like JSON or local files) to Kvrocks requires custom scripting using the `KvrocksStorage` API to import historical records into the new key-value store.