Files
linearvoid/SETUP.md
T

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

  1. Clone the Repository (if not already done):

    git clone https://git.allucanget.biz/zwitschi/linearvoid.git
    cd linearvoid
    
  2. Copy Environment File:

    cp .env.example .env
    
  3. 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
    
  4. Create Data Directories:

    mkdir -p data/playlist data/media data/hls data/chat
    
  5. Prepare Sample Videos (optional):

    • Place normalized MP4 files in data/media/.
    • Create a data/playlist/playlist.txt with paths (see ADR-001 for normalization requirements).

Running the Application

Local Development

  1. Start All Services:

    docker compose up --build
    
  2. Access the Application:

  3. Frontend Development (optional, for UI changes):

    cd frontend
    npm run dev
    

    The dev server runs on http://localhost:5173. It proxies API calls to the backend services.

  4. Stop Services:

    docker compose down
    

Production Deployment (Hetzner VPS + Cloudflare)

  1. Provision VPS: Use Hetzner Cloud CX22 in Ashburn, VA (per ADR-001).
  2. Configure Cloudflare:
    • Create R2 bucket with enam location hint.
    • Set up custom domain (media.example.com) with the cache rules from infrastructure/cloudflare/cache-rules.md.
    • Apply the Worker from infrastructure/cloudflare/worker.js for advanced header management.
  3. 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.
  4. 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 .env and ensure the bucket exists. Verify with aws s3 ls --endpoint-url=$R2_ENDPOINT.
  • Normalization Errors: Run backend/playout/start-playout.sh manually 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 /health should 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 logs for 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