From cb36cfa18d9b233f3b509b38762c793d65f2906a Mon Sep 17 00:00:00 2001 From: zwitschi Date: Sun, 2 Aug 2026 17:29:32 +0200 Subject: [PATCH] add setup guide --- SETUP.md | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 SETUP.md diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 0000000..02cff82 --- /dev/null +++ b/SETUP.md @@ -0,0 +1,139 @@ +# 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`) and ADRs in `docs/architecture/adr/`. + +## Prerequisites + +- **Docker & Docker Compose**: Required for running the full stack (playout, chat, nginx, redis, db, prometheus, grafana). Install from [docker.com](https://www.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): + + ```bash + git clone + cd linearvoid + ``` + +2. **Copy Environment File**: + + ```bash + cp .env.example .env + ``` + +3. **Configure `.env`** (edit with your values): + + ```env + # 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 + + # 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**: + + ```bash + 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**: + + ```bash + docker compose up --build + ``` + +2. **Access the Application**: + - Viewer: + - Chat WebSocket: ws://localhost:3000/ws + - Admin Interface: (use the credentials from `.env` or default admin/admin) + - Health Checks: + - Playout: + - Chat: + - Monitoring: + - Prometheus: + - Grafana: (default login: admin/admin) + +3. **Frontend Development** (optional, for UI changes): + + ```bash + cd frontend + npm run dev + ``` + + The dev server runs on . It proxies API calls to the backend services. + +4. **Stop Services**: + + ```bash + 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. + - Run `docker compose up -d --build`. + - 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