From 132ce04e0c80ef34a1f67d01f6e3a00d677e0973 Mon Sep 17 00:00:00 2001 From: Daniel Michelberger Date: Thu, 6 Aug 2026 14:06:30 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20pb=5Fmigrations=20nicht=20mounten=20?= =?UTF-8?q?=E2=80=94=20Deployment=20startete=20ohne=20Collections?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der in 22cd427 ergänzte Bind-Mount ./pb_migrations:/pb/pb_migrations überdeckt das Verzeichnis aus dem Image. Auf einem Deployment-Host, neben dessen compose-Datei kein ausgechecktes Repo liegt, legt Docker dort ein leeres Verzeichnis an: PocketBase findet keine Migration und startet mit einer Datenbank ohne Collections. Genau das ist auf der neu deployten Instanz passiert — users war da (legt PocketBase selbst an), events, teams, riders, runs und times fehlten. Reproduziert und beide Richtungen verifiziert: mit leerem Mount 404 auf allen fünf Collections, ohne Mount kommen alle sechs aus dem Image. Die Migrationen kommen damit wieder ausschließlich über COPY ins Image. Der Preis ist der Weg zurück: Im Admin-UI erzeugte Migrationen liegen nur im Container und müssen mit "docker compose cp" ins Repo geholt werden. Das steht jetzt in backend/README.md und CLAUDE.md. Co-Authored-By: Claude Opus 5 (1M context) --- CLAUDE.md | 7 +++++-- backend/README.md | 20 ++++++++++++++++++-- backend/docker-compose.yaml | 17 +++++++++++------ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index dea97d9..91636b0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -53,8 +53,11 @@ docker compose down - **API Base URL**: konfigurierbar über `PUBLIC_PB_URL` in `frontend/.env`. Default ist die produktive Instanz `https://api.stammtisch-hersbruck.de`; für das lokale Backend aus `backend/` auf `http://127.0.0.1:8090` umstellen. -- **Schema**: versioniert als Migration in `backend/pb_migrations/`. Änderungen - im Admin-UI erzeugen dort neue Dateien, die committet werden müssen. +- **Schema**: versioniert als Migration in `backend/pb_migrations/`, kommt per + `COPY` ins Image (kein Bind-Mount — der würde das Image-Verzeichnis + überdecken). Im Admin-UI erzeugte Migrationen liegen deshalb zunächst nur im + Container und müssen mit `docker compose cp` ins Repo geholt werden; siehe + `backend/README.md`. - **Type-safe client**: The PocketBase client is typed using auto-generated types in `frontend/src/lib/types.d.ts` - **Collections**: users, teams, events, runs, riders, times - **Authentication**: Handled through `src/lib/stores/pocketbase.svelte.ts` with the `AuthStore` class diff --git a/backend/README.md b/backend/README.md index b1b5c66..9c21aa9 100644 --- a/backend/README.md +++ b/backend/README.md @@ -28,8 +28,24 @@ per `GET /api/collections` abgezogen und ruft `importCollections` mit `deleteMissing = false` auf — die Migration legt an und aktualisiert, löscht aber nichts, was nicht im Snapshot steht. -Schema-Änderungen im Admin-UI erzeugen in `pb_migrations/` neue Dateien; diese -müssen committet werden. +### Schema-Änderungen aus dem Admin-UI holen + +`pb_migrations/` wird **nicht** in den Container gemountet — die Migrationen +kommen über `COPY` ins Image (siehe `Dockerfile`). Das ist Absicht: Ein +Bind-Mount überdeckt das Image-Verzeichnis, und auf einem Deployment-Host ohne +ausgechecktes Repo legt Docker dort ein leeres Verzeichnis an. PocketBase +findet dann keine Migration und startet mit einer Datenbank ohne Collections. + +Die Kehrseite: Eine im Admin-UI erzeugte Migration liegt zunächst nur im +Container und muss von Hand herausgeholt werden: + + # Welche Dateien sind dazugekommen? + docker compose exec pocketbase ls /pb/pb_migrations + + # Die neue Datei ins Repo kopieren und committen + docker compose cp pocketbase:/pb/pb_migrations/ ./pb_migrations/ + +Ohne diesen Schritt ist die Änderung beim nächsten `--build` verloren. Ein frisch gestarteter Container hat damit dasselbe Schema wie die produktive Instanz — aber **keine** Daten. diff --git a/backend/docker-compose.yaml b/backend/docker-compose.yaml index 0fab6e0..ba70fdd 100644 --- a/backend/docker-compose.yaml +++ b/backend/docker-compose.yaml @@ -14,12 +14,17 @@ services: # Redeploy alles weg — das Schema käme zwar aus pb_migrations zurück, # die Daten aber nicht. - ./pb_data:/pb/pb_data - # Migrationen zurück auf den Host. Ohne dieses Mapping schreibt PocketBase - # die bei Schema-Änderungen im Admin-UI erzeugten Dateien nur ins - # Container-Dateisystem — sie wären beim nächsten Build verloren und - # könnten nie committet werden. Das COPY im Dockerfile bleibt trotzdem - # bestehen, damit das Image auch ohne Bind-Mount das Schema mitbringt. - - ./pb_migrations:/pb/pb_migrations + # ACHTUNG: pb_migrations wird bewusst NICHT gemountet. Ein Bind-Mount + # überdeckt das Verzeichnis aus dem Image. Liegt auf dem Host kein + # ausgechecktes Repo daneben, legt Docker ein leeres Verzeichnis an — + # PocketBase findet dann keine einzige Migration und startet mit einer + # Datenbank ohne Collections. Genau das ist bei einem Deployment + # passiert, das nur die compose-Datei kennt. + # + # Die Migrationen kommen deshalb ausschließlich über COPY ins Image + # (siehe Dockerfile). Im Admin-UI erzeugte Migrationen landen damit nur + # im Container und müssen von Hand herausgeholt werden: + # docker compose cp pocketbase:/pb/pb_migrations/ ./pb_migrations/ environment: # Superuser wird nur beim allerersten Start angelegt (siehe entrypoint.sh) SUPERUSER_EMAIL: ${SUPERUSER_EMAIL:-}