8ed8da2d907f61d3db92f24bb019e68efc6c11ee
Area 1 (tv/page.tsx 964→423 lines): - hooks: use-fullscreen, use-idle, use-volume, use-quality, use-subtitles, use-channel-input, use-channel-passwords, use-tv-keyboard - components: SubtitlePicker, VolumeControl, QualityPicker, TopControlBar, LogoWatermark, AutoplayPrompt, ChannelNumberOverlay, TvBaseLayer Area 2 (edit-channel-sheet.tsx 1244→678 lines): - hooks: use-channel-form (all form state + reset logic) - lib/schemas.ts: extracted Zod schemas + extractErrors - components: AlgorithmicFilterEditor, RecyclePolicyEditor, WebhookEditor, AccessSettingsEditor, LogoEditor Area 3 (dashboard/page.tsx 406→261 lines): - hooks: use-channel-order, use-import-channel, use-regenerate-all - lib/channel-export.ts: pure export utility - components: DashboardHeader
k-tv
Self-hosted linear TV channel orchestration. Turns a personal media library into broadcast-style channels.
Stack
- Backend — Rust (Axum), SQLite/PostgreSQL, Jellyfin
- Frontend — Next.js 16, React 19, TanStack Query, Tailwind v4, shadcn/ui
Docker
Registry: registry.gabrielkaszewski.dev
Build
NEXT_PUBLIC_API_URL is baked into the frontend bundle at build time — always pass it explicitly.
# Backend
docker build -t registry.gabrielkaszewski.dev/k-tv-backend:latest ./k-tv-backend
# Frontend — NEXT_PUBLIC_API_URL required
docker build \
--build-arg NEXT_PUBLIC_API_URL=https://tv-api.gabrielkaszewski.dev/api/v1 \
-t registry.gabrielkaszewski.dev/k-tv-frontend:latest \
./k-tv-frontend
Push
docker push registry.gabrielkaszewski.dev/k-tv-backend:latest
docker push registry.gabrielkaszewski.dev/k-tv-frontend:latest
Build + push (one-liner)
docker build -t registry.gabrielkaszewski.dev/k-tv-backend:latest ./k-tv-backend && \
docker push registry.gabrielkaszewski.dev/k-tv-backend:latest && \
docker build \
--build-arg NEXT_PUBLIC_API_URL=https://tv-api.gabrielkaszewski.dev/api/v1 \
-t registry.gabrielkaszewski.dev/k-tv-frontend:latest \
./k-tv-frontend && \
docker push registry.gabrielkaszewski.dev/k-tv-frontend:latest
Deploy (on server)
docker compose -f compose.yml -f compose.traefik.yml pull
docker compose -f compose.yml -f compose.traefik.yml up -d
Ports
| Service | Port |
|---|---|
| Backend | 3000 |
| Frontend | 3001 |
Env vars
| Var | Where | Note |
|---|---|---|
NEXT_PUBLIC_API_URL |
frontend build arg | Baked in at build time — must point to the public backend URL |
API_URL |
frontend runtime env | Server-side only (Next.js API routes). Set in compose. |
DATABASE_URL |
backend | sqlite:///app/data/k-tv.db or postgres DSN |
JWT_SECRET |
backend | JWT signing key — change in production (min 32 chars) |
COOKIE_SECRET |
backend | OIDC state cookie encryption key — change in production (min 64 chars) |
Description
Languages
TypeScript
55.4%
Rust
43.9%
CSS
0.4%
Dockerfile
0.2%