Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11d48c8e0d | ||
|
|
242fc8da67 |
No files matched your search
+74
-73
@@ -1,73 +1,74 @@
|
||||
# Environment variables for Linear Void
|
||||
# Copy to .env and fill in real values for local/development use.
|
||||
# Production secrets should be managed via Docker secrets, Cloudflare, or Hetzner environment.
|
||||
|
||||
# Cloudflare R2 (S3-compatible)
|
||||
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
|
||||
R2_REGION=auto
|
||||
R2_KEEP_RUNS=2
|
||||
R2_MAX_RETENTION_BYTES=10737418240
|
||||
|
||||
# Cloudflare (for custom domain, cache rules, Workers if used)
|
||||
CLOUDFLARE_API_TOKEN=your-cloudflare-api-token
|
||||
CLOUDFLARE_ACCOUNT_ID=your-account-id
|
||||
MEDIA_DOMAIN=media.linearvoid.tv
|
||||
|
||||
# Public frontend URLs (Vite reads these from the repository root via frontend/vite.config.ts)
|
||||
# Preferred local setup in this repo uses the real public domains through Cloudflare/Nginx Proxy Manager.
|
||||
VITE_PUBLIC_APP_URL=https://linearvoid.tv
|
||||
VITE_PUBLIC_WS_URL=wss://linearvoid.tv/ws
|
||||
VITE_PUBLIC_HLS_URL=https://media.linearvoid.tv/hls/playlist.m3u8
|
||||
VITE_PUBLIC_ADMIN_DEFAULT_MODERATOR=admin
|
||||
VITE_PUBLIC_ADMIN_DEFAULT_ROOM=main
|
||||
VITE_PUBLIC_ADMIN_MODERATION_LOG_LIMIT=50
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=change-me
|
||||
ADMIN_SESSION_TTL_HOURS=12
|
||||
# Optional direct-local fallback when bypassing the public proxy:
|
||||
# VITE_PUBLIC_APP_URL=http://localhost
|
||||
# VITE_PUBLIC_WS_URL=ws://localhost/ws
|
||||
# VITE_PUBLIC_HLS_URL=http://localhost/hls/playlist.m3u8
|
||||
|
||||
# Gitea Container Registry (for self-hosted Docker images)
|
||||
CI_REGISTRY_URL=git.allucanget.biz
|
||||
CI_REGISTRY_USER=your-gitea-username
|
||||
CI_REGISTRY_TOKEN=your-gitea-token
|
||||
CI_REGISTRY_NAMESPACE=zwitschi/linearvoid
|
||||
# Gitea API access (optional, for CI/release automation)
|
||||
CI_SERVER_URL=https://git.allucanget.biz
|
||||
|
||||
# Chat / Application Database (compose-safe PostgreSQL by default, SQLite optional)
|
||||
DATABASE_URL=postgres://linearvoid:linearvoid@db:5432/linearvoid?sslmode=disable
|
||||
# Or for SQLite-only local development:
|
||||
# DATABASE_URL=sqlite://./data/chat.db
|
||||
|
||||
# Redis (for presence, rate limiting, pub/sub)
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
|
||||
# Service Ports (for local docker-compose)
|
||||
PLAYOUT_PORT=8080
|
||||
CHAT_PORT=3000
|
||||
NGINX_PORT=80
|
||||
|
||||
# Playout configuration
|
||||
PLAYLIST_PATH=/app/playlist/playlist.txt
|
||||
HLS_SEGMENT_DURATION=2
|
||||
HLS_WINDOW_SIZE=12
|
||||
|
||||
# Shared runtime config (written by chat admin via /api/admin/config, read by playout).
|
||||
# Both resolve to the same host file through the ./data/playlist volume.
|
||||
CONFIG_PATH=/app/playlist/config.json
|
||||
PLAYOUT_CONFIG_PATH=/app/playlist/config.json
|
||||
|
||||
# Logging / Monitoring
|
||||
LOG_LEVEL=info
|
||||
PROMETHEUS_PORT=9090
|
||||
GRAFANA_PORT=3001
|
||||
|
||||
# Development flags
|
||||
NODE_ENV=development
|
||||
GO_ENV=development
|
||||
# Environment variables for Linear Void
|
||||
# Copy to .env and fill in real values for local/development use.
|
||||
# Production secrets should be managed via Docker secrets, Cloudflare, or Hetzner environment.
|
||||
|
||||
# Cloudflare R2 (S3-compatible)
|
||||
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
|
||||
R2_REGION=auto
|
||||
R2_KEEP_RUNS=2
|
||||
R2_MAX_RETENTION_BYTES=10737418240
|
||||
|
||||
# Cloudflare (for custom domain, cache rules, Workers if used)
|
||||
CLOUDFLARE_API_TOKEN=your-cloudflare-api-token
|
||||
CLOUDFLARE_ACCOUNT_ID=your-account-id
|
||||
MEDIA_DOMAIN=media.linearvoid.tv
|
||||
|
||||
# Public frontend URLs (Vite reads these from the repository root via frontend/vite.config.ts)
|
||||
# Preferred local setup in this repo uses the real public domains through Cloudflare/Nginx Proxy Manager.
|
||||
VITE_PUBLIC_APP_URL=https://linearvoid.tv
|
||||
VITE_PUBLIC_WS_URL=wss://linearvoid.tv/ws
|
||||
VITE_PUBLIC_HLS_URL=https://media.linearvoid.tv/hls/playlist.m3u8
|
||||
VITE_PUBLIC_ADMIN_DEFAULT_MODERATOR=admin
|
||||
VITE_PUBLIC_ADMIN_DEFAULT_ROOM=main
|
||||
VITE_PUBLIC_ADMIN_MODERATION_LOG_LIMIT=50
|
||||
ADMIN_USERNAME=admin
|
||||
ADMIN_PASSWORD=change-me
|
||||
ADMIN_SESSION_TTL_HOURS=12
|
||||
# Optional direct-local fallback when bypassing the public proxy:
|
||||
# VITE_PUBLIC_APP_URL=http://localhost
|
||||
# VITE_PUBLIC_WS_URL=ws://localhost/ws
|
||||
# VITE_PUBLIC_HLS_URL=http://localhost/hls/playlist.m3u8
|
||||
|
||||
# Gitea Container Registry (for self-hosted Docker images)
|
||||
CI_REGISTRY_URL=git.allucanget.biz
|
||||
CI_REGISTRY_USER=your-gitea-username
|
||||
CI_REGISTRY_TOKEN=your-gitea-token
|
||||
CI_REGISTRY_NAMESPACE=zwitschi/linearvoid
|
||||
# Gitea API access (optional, for CI/release automation)
|
||||
CI_SERVER_URL=https://git.allucanget.biz
|
||||
|
||||
# Chat / Application Database (compose-safe PostgreSQL by default, SQLite optional)
|
||||
DATABASE_URL=postgres://linearvoid:linearvoid@db:5432/linearvoid?sslmode=disable
|
||||
# Or for SQLite-only local development:
|
||||
# DATABASE_URL=sqlite://./data/chat.db
|
||||
|
||||
# Redis (for presence, rate limiting, pub/sub)
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
|
||||
# Service Ports (for local docker-compose)
|
||||
# Coolify env: 80/443 (Traefik proxy), 8000 (dashboard/Portainer), 8080 taken.
|
||||
PLAYOUT_PORT=8081
|
||||
CHAT_PORT=3000
|
||||
NGINX_PORT=8082
|
||||
|
||||
# Playout configuration
|
||||
PLAYLIST_PATH=/app/playlist/playlist.txt
|
||||
HLS_SEGMENT_DURATION=2
|
||||
HLS_WINDOW_SIZE=12
|
||||
|
||||
# Shared runtime config (written by chat admin via /api/admin/config, read by playout).
|
||||
# Both resolve to the same host file through the ./data/playlist volume.
|
||||
CONFIG_PATH=/app/playlist/config.json
|
||||
PLAYOUT_CONFIG_PATH=/app/playlist/config.json
|
||||
|
||||
# Logging / Monitoring
|
||||
LOG_LEVEL=info
|
||||
PROMETHEUS_PORT=9090
|
||||
GRAFANA_PORT=3001
|
||||
|
||||
# Development flags
|
||||
NODE_ENV=development
|
||||
GO_ENV=development
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
### Changed
|
||||
|
||||
- **Coolify host-port de-collision**: Published playout on host port `8081` (`${PLAYOUT_PORT:-8081}:8081`) and moved the nginx host port from `8080`/`80` to a free `8082` (`${NGINX_PORT:-8082}:80`) in both `docker-compose.yml` and `docker-compose.prod.yml`, so no service binds ports reserved by the Coolify environment (Traefik proxy `80`/`443`, dashboard/Portainer `8000`, and the taken `8080`). `NGINX_PORT` default in `.env.example` updated from `80` to `8082`.
|
||||
|
||||
- **Docs condensed and de-Windows'd**: Removed Windows/PowerShell-specific instructions from the docs and condensed the longest documents into tighter, bash-first guides — `SETUP.md`, `DEPLOYMENT.md`, `API.md`, `MONITORING.md`, `STREAMING.md`, `COOLIFY.md`, `incident-runbook.md`, `operations/scaling-performance-playbook.md`, `architecture/README.md`, and the Prometheus metrics inventory. `scripts/loadtest/README.md` now documents the bash load-test helpers.
|
||||
- **System messages no longer persisted**: The chat backend no longer stores `system`-type messages; chat history and the admin chat-log table only contain real chat messages (moderation actions remain in the audit log).
|
||||
- **Reconnect grace period**: Disconnects schedule a delayed "left" announcement (5s); a reconnect within 5s cancels it and skips "joined", eliminating join/leave spam on brief reconnects.
|
||||
|
||||
@@ -11,6 +11,8 @@ services:
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${PLAYOUT_PORT:-8081}:8081"
|
||||
volumes:
|
||||
- ./data/playlist:/app/playlist:rw
|
||||
- ./data/media:/app/media:ro
|
||||
@@ -56,7 +58,7 @@ services:
|
||||
container_name: linearvoid-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${NGINX_PORT:-8080}:80"
|
||||
- "${NGINX_PORT:-8082}:80"
|
||||
volumes:
|
||||
- ./data/hls:/srv/hls:ro
|
||||
networks:
|
||||
|
||||
+3
-1
@@ -13,6 +13,8 @@ services:
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "${PLAYOUT_PORT:-8081}:8081"
|
||||
volumes:
|
||||
- ./data/playlist:/app/playlist:ro
|
||||
- ./data/media:/app/media:ro
|
||||
@@ -64,7 +66,7 @@ services:
|
||||
container_name: linearvoid-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${NGINX_PORT:-8080}:80"
|
||||
- "${NGINX_PORT:-8082}:80"
|
||||
volumes:
|
||||
- ./frontend/dist:/srv/frontend:ro
|
||||
- ./data/hls:/srv/hls:ro
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ mkdir -p data/playlist data/media data/hls data/chat
|
||||
### Domains and proxy
|
||||
|
||||
1. Assign the **nginx** service a public domain (e.g. `linearvoid.tv`); Traefik terminates TLS and forwards to `nginx`.
|
||||
2. Set **Ports Exposes** so Traefik targets the nginx port (`80` inside container, mapped from `${NGINX_PORT:-8080}:80`).
|
||||
2. Set **Ports Exposes** so Traefik targets the nginx port (`80` inside container, mapped from `${NGINX_PORT:-8082}:80`).
|
||||
3. Do **not** publicly expose playout (`8081`) or chat (`3000`) health ports — keep them internal and route through nginx.
|
||||
4. For `media.linearvoid.tv`, keep serving HLS from the R2 custom domain (per SETUP.md) rather than routing through Coolify, so segments stay on Cloudflare's edge cache.
|
||||
|
||||
|
||||
Reference in new issue
Block a user