refactor(docker): docker-compose.yml ist der Pull-Weg, Bauen wandert nach .dev.yml

Namen getauscht: das Standard-Compose zieht jetzt die fertigen Registry-Images
(vorher docker-compose.prod.yml), die Build-Variante heisst docker-compose.dev.yml.
Weniger verwirrend, weil der Produktivfall ohne -f auskommt. Kopfkommentare,
README, CLAUDE.md, .env.example und build-push-images.mjs entsprechend angepasst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-09-02 16:15:46 +02:00
1 parent 62391e4aae
commit 043ec3a108
6 files changed
+53 -53

No files matched your search

+3 -3
View File
@@ -1,6 +1,6 @@
# Copy to .env next to your docker-compose file and fill in. cp .env.example .env
# Used by docker-compose.yml (builds locally from the Dockerfiles).
# The REGISTRY/TAG at the bottom are only for the optional pull-from-registry / CI flow.
# Used by docker-compose.yml (zieht fertige Images) und docker-compose.dev.yml (baut lokal).
# REGISTRY/TAG unten braucht nur der Pull-Weg (docker-compose.yml).
# ── URLs pre-filled on the frontend setup screen ─────────────────────────────
NAVIDROME_URL=https://music.example.com
@@ -23,7 +23,7 @@ GITEA_REPO=Docker/NovaSonic
GITEA_TOKEN= # read token (only needed for a private repo)
GITEA_APK_TAG=apk-latest
# ── Pre-built images (docker-compose.yml only) ───────────────────────────────
# ── Fertige Images (nur docker-compose.yml) ──────────────────────────────────
# REGISTRY = where `npm run push-images` pushed to and where the host pulls from.
# Gitea container registry (lowercase owner): gitea.honeyy.duckdns.org/docker
# Docker Hub: docker.io/youruser
+13 -12
View File
@@ -41,19 +41,20 @@ npm run build # production build → dist/
npm run preview # preview the production build
```
Backend runs in Docker via **`docker-compose.yml`**, which **builds locally from the Dockerfiles**
(`backend/Dockerfile` + `scrobble/Dockerfile`). The heavy deps (ffmpeg, Deno, yt-dlp, node libs) are
baked into the images, so container **restarts are instant** and a rebuild after `git pull` is fast
(Docker caches the dep layers — only the code COPY layer changes). Deploy: `git pull && docker compose
up -d --build`; a plain restart is `docker compose restart novasonic-backend` (the backend also
re-pulls the latest yt-dlp on each start). No registry needed for that path.
Der Stack läuft in Docker. **`docker-compose.yml` ist der Normalfall und zieht fertige Images**
(`${REGISTRY}/novasonic-frontend|-backend|-scrobble:${TAG:-latest}`) — der Server baut nichts:
`docker compose pull && docker compose up -d`. Ein einfacher Restart ist `docker compose restart
novasonic-backend` (das Backend zieht bei jedem Start das neueste yt-dlp nach).
**Produktivsystem zieht stattdessen fertige Images** — `docker-compose.prod.yml` referenziert
`${REGISTRY}/novasonic-frontend|-backend|-scrobble:${TAG:-latest}` und baut nichts:
`docker compose -f docker-compose.prod.yml pull && … up -d`. Gepusht wird von der Dev-Maschine mit
`npm run push-images` (`scripts/build-push-images.mjs`, liest `REGISTRY`/`TAG` aus `.env`); ohne Node
tut es direkt `docker build -t $REGISTRY/<name>:latest <context>` + `docker push` mit den Kontexten
`.`, `backend/`, `scrobble/`. Registry ist die Gitea-Registry (`…/docker`, Owner klein geschrieben).
Gepusht wird von der Dev-Maschine mit `npm run push-images` (`scripts/build-push-images.mjs`, liest
`REGISTRY`/`TAG` aus `.env`); ohne Node tut es direkt `docker build -t $REGISTRY/<name>:latest
<context>` + `docker push` mit den Kontexten `.`, `backend/`, `scrobble/`. Registry ist die
Gitea-Registry (`…/docker`, Owner klein geschrieben).
**`docker-compose.dev.yml`** ist die Variante, die stattdessen lokal aus den Dockerfiles baut
(`backend/Dockerfile` + `scrobble/Dockerfile`), ohne Registry: `docker compose -f
docker-compose.dev.yml up -d --build`. Die schweren Deps (ffmpeg, Deno, yt-dlp, node libs) sind in
den Images gebacken, deshalb sind **Restarts sofort da** und Rebuilds nach `git pull` cache-schnell.
On the deploy host the music lives at `/opt/navidrome/music`.
+13 -12
View File
@@ -87,8 +87,8 @@ NovaSonic/
├── styles.css
├── vite.config.js
├── Dockerfile
├── docker-compose.yml
├── docker-compose.prod.yml # Produktiv: zieht fertige Images aus der Registry
├── docker-compose.yml # Standard: zieht die fertigen Images aus der Registry
├── docker-compose.dev.yml # Variante: baut lokal aus den Dockerfiles
├── nginx.conf
└── docker-entrypoint.sh # Injects NAVIDROME_URL / BACKEND_URL / SCROBBLE_URL at runtime
```
@@ -124,23 +124,24 @@ TICKETMASTER_API_KEY= # optional — free key from developer.ticketmaster.com
### 2. Start
```bash
docker compose up -d --build
docker compose pull
docker compose up -d
```
Builds locally from the Dockerfiles (deps baked in → instant restarts; rebuilds after a `git pull`
are fast thanks to Docker's layer cache). No registry needed.
Zieht die drei fertigen Images aus der Registry — nichts wird auf dem Server gebaut. Dafür in der
`.env` `REGISTRY` (und optional `TAG`) setzen; die Images heißen
`$REGISTRY/novasonic-frontend|-backend|-scrobble`. Neue Stände lädt man von der Dev-Maschine mit
`npm run push-images` hoch (bzw. `docker build -t $REGISTRY/<name>:latest <context> && docker push …`
— Kontexte: `.` (frontend), `backend/`, `scrobble/`).
**Produktiv ohne Bauen** — die drei Images kommen fertig aus der Registry:
**Selbst bauen statt ziehen** (keine Registry nötig):
```bash
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
docker compose -f docker-compose.dev.yml up -d --build
```
Dafür in der `.env` `REGISTRY` (und optional `TAG`) setzen; die Images heißen
`$REGISTRY/novasonic-frontend|-backend|-scrobble`. Neue Stände von der Dev-Maschine aus mit
`npm run push-images` (bzw. `docker build -t $REGISTRY/<name>:latest <context> && docker push …`)
hochladen — Kontexte: `.` (frontend), `backend/`, `scrobble/`.
Baut lokal aus den Dockerfiles; die Deps stecken in den Images, also sind Restarts sofort da und
Rebuilds nach einem `git pull` dank Layer-Cache schnell.
Frontend on port 8080, backend on port 3700, scrobble service on port 3710. Route each through your reverse proxy. **Important:** the scrobble subdomain must *not* sit behind an SSO / forward-auth gateway — it authenticates itself via Navidrome (`ping.view`), and a gateway in front redirects the app's API calls to a login page.
@@ -1,17 +1,17 @@
# NovaSonic — PRODUKTIV: zieht die fertigen Images aus der Registry, baut nichts.
# Auf dem Server nur .env danebenlegen (siehe .env.example) und:
# NovaSonic — DEV/Selbstbauen: baut lokal aus den Dockerfiles statt Images zu ziehen. Die schweren
# Deps (ffmpeg, Deno, yt-dlp, node libs) stecken in den Images, also sind RESTARTS sofort da und ein
# Rebuild nach Code-Änderungen ist schnell (Docker cacht die Dep-Layer — nur der COPY-Layer ändert sich).
#
# docker compose -f docker-compose.prod.yml pull
# docker compose -f docker-compose.prod.yml up -d
# git pull
# docker compose -f docker-compose.dev.yml up -d --build # geänderte Images neu bauen + starten
# docker compose -f docker-compose.dev.yml up -d # nur starten, mit den gebauten Images
#
# Die Images kommen von der Dev-Maschine: `npm run push-images`
# (baut die drei Dockerfiles und pusht nach ${REGISTRY}). Zum Bauen auf dem Host
# stattdessen das normale docker-compose.yml nehmen.
# Keine Registry nötig. Der Normalfall (fertige Images ziehen) ist docker-compose.yml.
services:
# ── Frontend (nginx serving the built PWA) ───────────────────────────────────
novasonic-frontend:
image: ${REGISTRY}/novasonic-frontend:${TAG:-latest}
build: .
container_name: novasonic-frontend
restart: unless-stopped
ports:
@@ -23,7 +23,8 @@ services:
# ── Backend (yt-dlp download server) ─────────────────────────────────────────
novasonic-backend:
image: ${REGISTRY}/novasonic-backend:${TAG:-latest}
build:
context: ./backend
container_name: novasonic-backend
restart: unless-stopped
volumes:
@@ -46,9 +47,10 @@ services:
- GITEA_TOKEN=${GITEA_TOKEN:-}
- GITEA_APK_TAG=${GITEA_APK_TAG:-apk-latest}
# ── Scrobble service (isolated timestamped play-log → stats + Wrapped) ───────
# ── Scrobble service (isolated timestamped play-log → stats + Wrapped) ────────
novasonic-scrobble:
image: ${REGISTRY}/novasonic-scrobble:${TAG:-latest}
build:
context: ./scrobble
container_name: novasonic-scrobble
restart: unless-stopped
volumes:
+10 -14
View File
@@ -1,18 +1,16 @@
# NovaSonic — builds locally from the Dockerfiles. The heavy deps (ffmpeg, Deno, yt-dlp, node libs)
# are baked into the images, so container RESTARTS are instant, and a rebuild after a code change is
# fast (Docker caches the dep layers — only the code COPY layer changes).
# NovaSonic — Standard/Produktiv: zieht die fertigen Images aus der Registry, baut nichts.
# Auf dem Server nur .env danebenlegen (siehe .env.example) und:
#
# git pull
# docker compose up -d --build # rebuild changed images (cached; fast) and (re)start
# docker compose up -d # just (re)start with the already-built images
# docker compose pull
# docker compose up -d
#
# No registry needed. (An optional pull-from-registry / CI flow can build these same Dockerfiles
# elsewhere and push — see scripts/build-push-images.mjs + .env.example.)
# Die Images kommen von der Dev-Maschine: `npm run push-images` (baut die drei Dockerfiles und
# pusht nach ${REGISTRY}). Selbst bauen statt ziehen: docker-compose.dev.yml.
services:
# ── Frontend (nginx serving the built PWA) ───────────────────────────────────
novasonic-frontend:
build: .
image: ${REGISTRY}/novasonic-frontend:${TAG:-latest}
container_name: novasonic-frontend
restart: unless-stopped
ports:
@@ -24,8 +22,7 @@ services:
# ── Backend (yt-dlp download server) ─────────────────────────────────────────
novasonic-backend:
build:
context: ./backend
image: ${REGISTRY}/novasonic-backend:${TAG:-latest}
container_name: novasonic-backend
restart: unless-stopped
volumes:
@@ -48,10 +45,9 @@ services:
- GITEA_TOKEN=${GITEA_TOKEN:-}
- GITEA_APK_TAG=${GITEA_APK_TAG:-apk-latest}
# ── Scrobble service (isolated timestamped play-log → stats + Wrapped) ────────
# ── Scrobble service (isolated timestamped play-log → stats + Wrapped) ───────
novasonic-scrobble:
build:
context: ./scrobble
image: ${REGISTRY}/novasonic-scrobble:${TAG:-latest}
container_name: novasonic-scrobble
restart: unless-stopped
volumes:
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env node
// Build the three NovaSonic images and push them to your registry, so the production host just PULLS
// (docker-compose.yml) instead of building. Run from your dev machine after changes:
// (docker-compose.yml) instead of building (that's docker-compose.dev.yml). Run from your dev machine:
//
// npm run push-images # builds + pushes REGISTRY/*:TAG (and :latest)
//