How to Deploy LunaTV Using Docker Compose: Complete Self-Hosting Guide
Deploy LunaTV by running the multi-stage container with required environment variables (USERNAME, PASSWORD, STORAGE_TYPE) and connecting it to Redis or Kvrocks via Docker Compose for persistent storage.
LunaTV from MoonTechLab/LunaTV provides a production-ready Docker setup that packages the Next.js application into a lightweight Alpine image. According to the repository source code, the deployment leverages a three-stage build process defined in Dockerfile to create a self-contained runtime that serves the UI on port 3000.
Understanding the Multi-Stage Build Architecture
The Dockerfile implements an optimized build pipeline that minimizes final image size and maximizes cache efficiency:
-
depsstage – Copies onlypackage.jsonand the lockfile to install Node dependencies using pnpm, ensuring layer caching remains effective when source code changes. -
builderstage – Inherits thenode_modulesfrom the previous stage, copies the full source tree, setsDOCKER_ENV=true, and executespnpm run buildto generate a standalone Next.js output in.next/standalone. -
runnerstage – Uses a clean Alpine base image, creates a non-rootnextjsuser, and copies only the essential artifacts: the standalone build, public assets, and the custom [start.js](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) entry point. The container launches vianode start.jslistening on0.0.0.0:3000.
Required Environment Variables
The container reads configuration from environment variables processed by [src/lib/config.ts](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/config.ts). You must provide the following at runtime:
| Variable | Purpose |
|---|---|
USERNAME / PASSWORD |
Administrator credentials for accessing the LunaTV dashboard (required). |
NEXT_PUBLIC_STORAGE_TYPE |
Backend for playback records: redis, kvrocks, or upstash. |
REDIS_URL / KVROCKS_URL / UPSTASH_URL / UPSTASH_TOKEN |
Connection string for the chosen storage backend. |
SITE_BASE / NEXT_PUBLIC_SITE_NAME |
Optional branding and base URL configuration. |
Single Container Deployment
For quick testing without Docker Compose, run the pre-built image directly from the GitHub Container Registry. This example connects to an external Redis instance:
docker run -d \
--name lunatv \
-p 3000:3000 \
-e USERNAME=admin \
-e PASSWORD=SuperSecretPassword \
-e NEXT_PUBLIC_STORAGE_TYPE=redis \
-e REDIS_URL=redis://host.docker.internal:6379 \
ghcr.io/moontechlab/lunatv:latest
Access the application at http://localhost:3000 after the container starts.
Docker Compose Deployment Strategies
Local Development with Redis
The repository provides [docker-compose.dev.yml](https://github.com/MoonTechLab/LunaTV/blob/main/docker-compose.dev.yml) as a reference implementation. This configuration builds the image from source and pairs it with a Redis container featuring persistent volume storage and health checks:
version: '3.8'
services:
redis:
image: redis:7-alpine
container_name: lunatv-redis
volumes:
- redis-data:/data
command: redis-server --appendonly yes
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 3s
retries: 5
app:
build:
context: .
dockerfile: Dockerfile
container_name: lunatv-app
ports:
- '3000:3000'
depends_on:
redis:
condition: service_healthy
environment:
- NEXT_PUBLIC_STORAGE_TYPE=redis
- REDIS_URL=redis://redis:6379
- USERNAME=admin
- PASSWORD=admin123
- NEXT_PUBLIC_SITE_NAME=MoonTV
volumes:
redis-data:
Production Deployment with Kvrocks
For production environments, the MoonTechLab/LunaTV source recommends Kvrocks (Redis-compatible persistent storage on SSD). Replace the Redis service in your Compose file with the following configuration:
services:
kvrocks:
image: apache/kvrocks
container_name: moontv-kvrocks
restart: unless-stopped
volumes:
- kvrocks-data:/var/lib/kvrocks
ports:
- "6666:6666"
app:
build:
context: .
dockerfile: Dockerfile
container_name: lunatv-app
ports:
- '3000:3000'
depends_on:
- kvrocks
environment:
- NEXT_PUBLIC_STORAGE_TYPE=kvrocks
- KVROCKS_URL=redis://kvrocks:6666
- USERNAME=admin
- PASSWORD=SecureProductionPass
volumes:
kvrocks-data:
Configuration Deep Dive
When the container starts, [start.js](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) serves as the custom entry point that pre-loads and validates environment variables before launching the Next.js standalone server. The [src/lib/config.ts](https://github.com/MoonTechLab/LunaTV/blob/main/src/lib/config.ts) module parses these variables at runtime, ensuring the storage backend connection and authentication credentials are properly initialized before accepting requests on port 3000.
Summary
- LunaTV uses a three-stage Dockerfile (
deps→builder→runner) to create optimized, production-ready images based on Alpine Linux. - Required variables: Set
USERNAME,PASSWORD, andNEXT_PUBLIC_STORAGE_TYPE(plus the corresponding backend URL) to launch the container successfully. - Development setup: Use [
docker-compose.dev.yml](https://github.com/MoonTechLab/LunaTV/blob/main/docker-compose.dev.yml) with Redis for local testing with automatic health checks. - Production setup: Deploy with Kvrocks for better persistence characteristics and configure restart policies for high availability.
- Access: The application binds to
0.0.0.0:3000inside the container, requiring port mapping to reach the UI externally.
Frequently Asked Questions
What storage backends does LunaTV support?
LunaTV supports three storage backends for playback records: Redis (for caching/labs), Kvrocks (recommended for production SSD persistence), and Upstash (managed Redis cloud service). Configure your choice via NEXT_PUBLIC_STORAGE_TYPE and the corresponding URL environment variable.
Why does the Dockerfile use a multi-stage build?
The multi-stage build defined in Dockerfile separates dependency installation, application compilation, and runtime execution. This approach reduces the final image size by excluding build tools and node_modules, resulting in a lightweight Alpine-based runner stage that contains only the compiled standalone output and the [start.js](https://github.com/MoonTechLab/LunaTV/blob/main/start.js) launcher.
Can I run LunaTV without Docker Compose?
Yes. Since the LunaTV image is self-contained, you can deploy it using simple docker run commands as long as you provide all required environment variables and network access to your chosen storage backend (Redis, Kvrocks, or Upstash). This works on Docker Desktop, Kubernetes, or platforms like Zeabur.
How do I persist data when using Docker Compose for LunaTV?
Data persistence depends on your storage backend selection. For Redis, mount a named volume to /data with the appendonly yes configuration. For Kvrocks, mount a volume to /var/lib/kvrocks. The example [docker-compose.dev.yml](https://github.com/MoonTechLab/LunaTV/blob/main/docker-compose.dev.yml) demonstrates Redis persistence using Docker volumes, while production Kvrocks deployments should use the same volume strategy to prevent data loss during container restarts.
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 →