5.4 KiB
Linear Void Setup Guide
This guide covers prerequisites, environment setup, running the application locally and in production, and troubleshooting. It references the architecture documentation(docs/architecture/README.md).
Prerequisites
- Docker & Docker Compose: Required for running the full stack (playout, chat, nginx, redis, db, prometheus, grafana). Install from docker.com.
- Node.js 20+: For frontend development (
cd frontend && npm run dev). - FFmpeg: Used by the playout service for HLS generation. Install via
apt install ffmpeg(Linux), Homebrew (macOS), or Winget (Windows). - Git: For cloning and version control.
- Cloudflare Account: For R2 storage and CDN (free tier sufficient for most use cases).
- Hetzner Cloud Account (optional for production): For the US-East VPS (Ashburn, VA recommended per ADR-001).
Environment Setup
-
Clone the Repository (if not already done):
git clone https://git.allucanget.biz/zwitschi/linearvoid.git cd linearvoid -
Copy Environment File:
cp .env.example .env -
Configure
.env(edit with your values):# Cloudflare R2 (required for video storage and $0 egress) R2_ACCESS_KEY_ID=your-r2-access-key R2_SECRET_ACCESS_KEY=your-r2-secret-key R2_BUCKET_NAME=linearvoid-media R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com # Cloudflare (for custom domain and cache rules) CLOUDFLARE_API_TOKEN=your-cloudflare-api-token MEDIA_DOMAIN=media.example.com # Gitea Container Registry (for self-hosted Docker images) GITEA_REGISTRY_URL=git.allucanget.biz GITEA_USERNAME=your-gitea-username GITEA_TOKEN=your-gitea-token GITEA_REGISTRY_NAMESPACE=zwitschi/linearvoid # Chat / Database REDIS_URL=redis://redis:6379/0 DATABASE_URL=sqlite://./data/chat.db # or postgres://user:pass@db:5432/linearvoid # Ports (for local development) CHAT_PORT=3000 NGINX_PORT=8080 PLAYOUT_HEALTH_PORT=8081 # Playout Configuration PLAYLIST_PATH=/app/playlist/playlist.txt HLS_SEGMENT_DURATION=6 HLS_WINDOW_SIZE=24 # Logging LOG_LEVEL=info -
Create Data Directories:
mkdir -p data/playlist data/media data/hls data/chat -
Prepare Sample Videos (optional):
- Place normalized MP4 files in
data/media/. - Create a
data/playlist/playlist.txtwith paths (see ADR-001 for normalization requirements).
- Place normalized MP4 files in
Running the Application
Local Development
-
Start All Services:
docker compose up --build -
Access the Application:
- Viewer: http://localhost:8080
- Chat WebSocket: ws://localhost:3000/ws
- Admin Interface: http://localhost:8080/admin (use the credentials from
.envor default admin/admin) - Health Checks:
- Playout: http://localhost:8081/health
- Chat: http://localhost:3000/health
- Monitoring:
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3001 (default login: admin/admin)
-
Frontend Development (optional, for UI changes):
cd frontend npm run devThe dev server runs on http://localhost:5173. It proxies API calls to the backend services.
-
Stop Services:
docker compose down
Production Deployment (Hetzner VPS + Cloudflare)
- Provision VPS: Use Hetzner Cloud CX22 in Ashburn, VA (per ADR-001).
- Configure Cloudflare:
- Create R2 bucket with
enamlocation hint. - Set up custom domain (
media.example.com) with the cache rules frominfrastructure/cloudflare/cache-rules.md. - Apply the Worker from
infrastructure/cloudflare/worker.jsfor advanced header management.
- Create R2 bucket with
- Deploy:
- Copy the project to the VPS.
- Use production compose:
docker compose -f docker-compose.prod.yml up -d - Or pull from Gitea registry:
docker compose -f docker-compose.prod.yml pull && docker compose -f docker-compose.prod.yml up -d - Configure systemd to manage the Docker Compose stack.
- Monitoring: Access Grafana at the exposed port for dashboards (included in
monitoring/grafana/dashboard.json).
See docs/architecture/README.md for the full arc42 documentation and the ADRs for architectural decisions.
Troubleshooting
- R2 Upload Fails: Check credentials in
.envand ensure the bucket exists. Verify withaws s3 ls --endpoint-url=$R2_ENDPOINT. - Normalization Errors: Run
backend/playout/start-playout.shmanually to see ffprobe output. All videos must be H.264/AAC, 30 fps constant, 2s keyframes (ADR-001). - Chat Not Connecting: Check Redis connection and WebSocket URL. The health check at
/healthshould return 200. - Cache Not Working: Verify Cloudflare cache rules (
.ts= long TTL immutable,.m3u8= short TTL). Check cache hit ratio in Cloudflare dashboard. - Docker Issues: Run
docker compose logsfor service-specific errors. Ensure ports are not in use. - Admin Interface: Ensure the protected route is configured in nginx and authentication is set up (default is open for local development).
Further Reading
- Architecture:
docs/architecture/README.md(arc42 template with diagrams). - Decisions:
docs/architecture/adr/(ADR-001 to ADR-007). - Contributing:
CONTRIBUTING.md. - Project Structure: Root
README.md.
The system is ready for use. For production, review ADR-001 for cost estimates and scaling guidance.
Last Updated: 2026-08-02