From 043ec3a1083e25713d1e0ffc148bd435ac573436 Mon Sep 17 00:00:00 2001 From: marc Date: Wed, 2 Sep 2026 16:15:46 +0200 Subject: [PATCH] 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 --- .env.example | 6 ++--- CLAUDE.md | 25 ++++++++++--------- README.md | 25 ++++++++++--------- ...compose.prod.yml => docker-compose.dev.yml | 24 ++++++++++-------- docker-compose.yml | 24 ++++++++---------- scripts/build-push-images.mjs | 2 +- 6 files changed, 53 insertions(+), 53 deletions(-) rename docker-compose.prod.yml => docker-compose.dev.yml (73%) diff --git a/.env.example b/.env.example index e8bb5f6..cd05863 100644 --- a/.env.example +++ b/.env.example @@ -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 diff --git a/CLAUDE.md b/CLAUDE.md index ce0276b..338590b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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/:latest ` + `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/:latest +` + `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`. diff --git a/README.md b/README.md index 05b5b99..dc0745a 100644 --- a/README.md +++ b/README.md @@ -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/:latest && 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/:latest && 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. diff --git a/docker-compose.prod.yml b/docker-compose.dev.yml similarity index 73% rename from docker-compose.prod.yml rename to docker-compose.dev.yml index 93ff685..2a98d63 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.dev.yml @@ -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: diff --git a/docker-compose.yml b/docker-compose.yml index b069ad3..a831b1c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -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: diff --git a/scripts/build-push-images.mjs b/scripts/build-push-images.mjs index 5192212..1203792 100644 --- a/scripts/build-push-images.mjs +++ b/scripts/build-push-images.mjs @@ -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) //