feat(docker): image-based prod stack (Dockerfiles + prod compose + push script)

Adds a pull-based production option so the host no longer builds/installs deps
on every restart:
- backend/Dockerfile + scrobble/Dockerfile bake the heavy deps (ffmpeg, Deno,
  yt-dlp, node libs). Backend still refreshes yt-dlp on start (non-fatal).
- docker-compose.prod.yml pulls ${REGISTRY}/novasonic-*:${TAG}.
- scripts/build-push-images.mjs (npm run push-images) builds + pushes all three.
- .env.example documents every var incl. REGISTRY/TAG; .env gitignored.

The build-on-host docker-compose.yml stays as-is.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-09-02 07:45:17 +02:00
1 parent 93ee958434
commit 149443e4f7
8 files changed
+205 -19

No files matched your search

+9 -3
View File
@@ -41,9 +41,15 @@ npm run build # production build → dist/
npm run preview # preview the production build
```
Backend runs in Docker (see `docker-compose.yml`); on the deploy host it lives at
`/opt/navidrome/music`. Restart after backend changes: `docker compose restart novasonic-backend`
(this also re-pulls the latest yt-dlp).
Backend runs in Docker. Two ways:
- **`docker-compose.yml`** — builds on the host (mounts `./backend`, installs deps at container
start). Restart after backend changes: `docker compose restart novasonic-backend` (re-pulls yt-dlp).
- **`docker-compose.prod.yml`** — PULLS pre-built images (deps baked into `backend/Dockerfile` +
`scrobble/Dockerfile`), so restarts are instant. Build+push from dev with `npm run push-images`
(needs `REGISTRY`/`TAG` in `.env`), then on the host `docker compose -f docker-compose.prod.yml pull
&& … up -d`. See `.env.example`.
On the deploy host the music lives at `/opt/navidrome/music`.
## Download pipeline (hard-won knowledge)