Queue reviewable Whisper drafts from the song list and lyrics editor. Preserve line breaks within one timed cue across editing, saving, reporting, and service views. Add storage and listening analytics with a durable metadata collector, related-search depth, video limits, thumbnail storage, and a browsable metadata library.
118 lines
5.2 KiB
YAML
118 lines
5.2 KiB
YAML
services:
|
|
ytplayer:
|
|
build: .
|
|
restart: unless-stopped
|
|
volumes:
|
|
# libsql DB file persists across container rebuilds
|
|
- ytplayer-data:/app/data
|
|
# Bulk media on the homelab's USB drive (/mnt/data, mounted nofail): the
|
|
# re-fetchable media cache and the uploads library. The DB, lyrics and
|
|
# notes stay on ytplayer-data. If the drive is missing, the marker file
|
|
# below is missing too: the cache pauses (playback streams) and uploads
|
|
# are served from the nightly backup copy on ytplayer-data.
|
|
- /mnt/data/ytplayer:/app/bulk
|
|
environment:
|
|
PORT: "3000"
|
|
MEDIA_DIR: "/app/bulk/media"
|
|
MEDIA_VOLUME_MARKER: "/app/bulk/.hl-data"
|
|
MEDIA_CACHE_MAX_BYTES: "268435456000" # 250 GiB of the 458 GiB drive
|
|
MEDIA_MIN_FREE_BYTES: "21474836480" # keep 20 GiB free on the drive
|
|
UPLOAD_DIR: "/app/bulk/uploads"
|
|
UPLOAD_VOLUME_MARKER: "/app/bulk/.hl-data"
|
|
# Second copy on the stable disk, refreshed nightly by
|
|
# scripts/ops/uploads-backup.sh on the homelab host; reads fall back to it.
|
|
UPLOAD_BACKUP_DIR: "/app/data/uploads-backup"
|
|
DB_PATH: "/app/data/ytplayer.db"
|
|
APP_VERSION: "1.0.0"
|
|
# Unlocks /admin (API tokens, lyric/chapter history + restore). Set it in
|
|
# Dokploy's Environment tab — never commit it. Unset = admin disabled.
|
|
ADMIN_PASSWORD: "${ADMIN_PASSWORD:-}"
|
|
# Phone remote: "1" = a phone may only pair with a screen on the same
|
|
# network (same public IP as seen by the server). Off by default.
|
|
REMOTE_SAME_NETWORK: "${REMOTE_SAME_NETWORK:-0}"
|
|
# Shared secret the lyrics-worker uses to list songs and upload lyrics.
|
|
# Set in Dokploy's Environment tab (same value feeds both services).
|
|
LYRICS_WORKER_TOKEN: "${LYRICS_WORKER_TOKEN:-}"
|
|
# Peer-to-peer sharing (docs/p2p-architecture.md). ON by default.
|
|
P2P_ENABLED: "${P2P_ENABLED:-1}"
|
|
# Malware scan before a file's hash is admitted. OFF by default; needs an
|
|
# image built with INSTALL_CLAMAV=1. Hashing + media validation always run.
|
|
P2P_MALWARE_SCAN: "${P2P_MALWARE_SCAN:-0}"
|
|
# P2P_STALE_DAYS: "7" # holder shown as stale after this many days unchecked
|
|
# P2P_KEEP_MIN_VIEWS: "3" # server keeps copies with ≥ this many views…
|
|
# P2P_KEEP_DAYS: "30" # …in this many days
|
|
# P2P_KEEP_RECENT_DAYS: "14" # …or played this recently
|
|
# P2P_INTAKE_DIR: "/app/data/p2p-intake" # quarantine for device uploads (never served)
|
|
# P2P_INTAKE_MAX_BYTES: "3221225472" # 3 GiB
|
|
# Optional: force yt-dlp search instead of InnerTube API
|
|
# SEARCH_INNERTUBE: "0" # force yt-dlp search
|
|
# Optional: override yt-dlp binary path if you mount a custom one
|
|
# YTDLP_PATH: "/usr/local/bin/yt-dlp"
|
|
# YTDLP_WORKER: "0" # disable the long-lived yt-dlp worker pool
|
|
# YTDLP_WORKERS: "2" # pool size
|
|
# Server media cache (server/media-cache.js) — defaults shown.
|
|
# (MEDIA_DIR / MEDIA_CACHE_MAX_BYTES / MEDIA_MIN_FREE_BYTES set above;
|
|
# defaults without them: /app/data/media, 10 GiB, 5 GiB)
|
|
# MEDIA_AUTO_MAX_SECONDS: "3600" # longest video auto-cached on play
|
|
# MEDIA_TRANSCODE: "1" # 0 disables the compression lane
|
|
# MEDIA_CODEC: "hevc" # hevc | h264
|
|
# MEDIA_CRF: "28"
|
|
# MEDIA_PRESET: "medium"
|
|
# MEDIA_THREADS: "2"
|
|
# MEDIA_OPT_MAX_SECONDS: "3600" # don't re-encode videos longer than this
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://localhost:3000/api/version"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 15s
|
|
networks:
|
|
- dokploy-network
|
|
- lyrics
|
|
labels:
|
|
- "traefik.enable=true"
|
|
- "traefik.http.routers.ytplayer-http.rule=Host(`worship.hesed.sbs`)"
|
|
- "traefik.http.routers.ytplayer-http.entrypoints=web"
|
|
- "traefik.http.routers.ytplayer-http.middlewares=redirect-to-https"
|
|
- "traefik.http.routers.ytplayer-https.rule=Host(`worship.hesed.sbs`)"
|
|
- "traefik.http.routers.ytplayer-https.entrypoints=websecure"
|
|
- "traefik.http.routers.ytplayer-https.tls.certresolver=letsencrypt"
|
|
- "traefik.http.services.ytplayer-svc.loadbalancer.server.port=3000"
|
|
|
|
# Handles requested Whisper drafts and transcribes saved songs without lyrics, with
|
|
# faster-whisper on CPU (no API keys, no credits). Separate container so it
|
|
# never competes with playback/downloads: capped CPU + memory, low priority,
|
|
# and it fetches audio from the ytplayer service over the private network.
|
|
lyrics-worker:
|
|
build: ./scripts/lyrics
|
|
restart: unless-stopped
|
|
depends_on:
|
|
- ytplayer
|
|
environment:
|
|
YTP_BASE: "http://ytplayer:3000"
|
|
YTP_TOKEN: "${LYRICS_WORKER_TOKEN:-}"
|
|
WHISPER_MODEL: "large-v3-turbo" # ~1.6 GB download on first start
|
|
WHISPER_THREADS: "2"
|
|
WATCH_SECONDS: "300"
|
|
volumes:
|
|
- lyrics-models:/models
|
|
- lyrics-state:/data
|
|
cpus: "2"
|
|
mem_limit: 3g
|
|
networks:
|
|
- lyrics
|
|
|
|
volumes:
|
|
ytplayer-data:
|
|
driver: local
|
|
lyrics-models:
|
|
driver: local
|
|
lyrics-state:
|
|
driver: local
|
|
|
|
networks:
|
|
dokploy-network:
|
|
external: true
|
|
lyrics:
|
|
driver: bridge
|