yt-dlp calls save_cookies() on exit and rewrites the --cookies file. A read-only
mount makes it crash with "OSError: [Errno 30] Read-only file system", which surfaced
as 500s on the app's YouTube search/download endpoints when YT_COOKIE_FILE was set.
YouTube playback relied on manual changes inside the running container
(deno install + /etc/yt-dlp.conf) that would be lost on any recreate.
Make it permanent and reproducible:
- Dockerfile.backend: install pinned deno 2.8.3 as yt-dlp's JS runtime and
write a system-wide /etc/yt-dlp.conf enabling the EJS challenge solver
(--js-runtimes deno, --remote-components ejs:github, --force-ipv4).
Replaces the unreliable node-based config.
- .gitea/workflows/build-backend.yml: build Dockerfile.backend and push
git.qomar.pw/omar/ts6-manager/backend:latest (amd64). Needs REGISTRY_TOKEN.
- docker-compose.yml: pull backend from the Gitea registry; frontend/sidecar
stay on upstream clusterzx images. Mount ./secrets read-only for optional
YouTube cookies via YT_COOKIE_FILE.
- gitignore/dockerignore: never commit cookies (live Google session).
- DEPLOY.md: deployment + CI notes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>