INBOX/checkpoint-updates-backup.md
2026-08-07 16:01:24 +02:00

253 lines
6.9 KiB
Markdown

# CheckPoint Ehrenamt — Updates & Datensicherung
> Vier Stufen von Änderungen · Backup-Strategie · Stand: Juni 2026
---
## Grundregel (immer)
**Vor jedem Update: Backup ziehen.** Kein Update ohne Backup — egal wie klein die
Änderung scheint.
---
## Backup manuell auslösen
```bash
docker exec checkpoint python3 -c "
import sqlite3
src = sqlite3.connect('/app/instance/checkpoint.sqlite')
dst = sqlite3.connect('/app/instance/latest-backup.sqlite')
src.backup(dst)
dst.close()
src.close()
"
```
Warum nicht einfach `cp`? SQLite schreibt in mehreren Schritten (WAL-Modus). Ein
roher Datei-Copy kann die Datenbank mitten in einem Schreibvorgang erwischen und
ein korruptes Backup erzeugen. `connection.backup()` macht einen konsistenten
Online-Snapshot — auch bei laufendem Betrieb sicher.
Backup prüfen:
```bash
docker exec checkpoint ls -lh /app/instance/
```
---
## Automatisches tägliches Backup (Cronjob)
Läuft täglich um 03:30 UTC auf dem VPS:
```
30 03 * * * docker exec checkpoint python3 -c "import sqlite3; src=sqlite3.connect('/app/instance/checkpoint.sqlite'); dst=sqlite3.connect('/app/instance/latest-backup.sqlite'); src.backup(dst); dst.close(); src.close()"
```
Cronjob anzeigen: `crontab -l`
Cronjob bearbeiten: `crontab -e`
**Wichtig:** Das Backup liegt im Docker-Volume auf dem VPS. Wenn der VPS ausfällt,
ist auch das Backup weg. Deshalb zusätzlich Ebene 3 (siehe unten).
---
## Backup vom VPS runterkopieren (Ebene 3)
Auf dem lokalen Rechner:
```bash
scp patsy@<vps-ip>:/var/lib/docker/volumes/checkpoint_checkpoint_data/_data/latest-backup.sqlite ./checkpoint-backup-$(date +%Y%m%d).sqlite
```
Mindestens einmal pro Woche, immer vor größeren Updates (Stufe 3 + 4).
---
## Die vier Update-Stufen
---
### Stufe 1 — Statische Dateien (CSS, JS, Bilder)
**Beispiele:** Farbe ändern, Button-Stil anpassen, Token-Werte in `tokens.css`.
**Risiko:** keines für die Daten.
**Vorgehen:**
```bash
# 1. Backup (Pflicht, auch hier)
docker exec checkpoint python3 -c "import sqlite3; src=sqlite3.connect('/app/instance/checkpoint.sqlite'); dst=sqlite3.connect('/app/instance/latest-backup.sqlite'); src.backup(dst); dst.close(); src.close()"
# 2. Code holen
cd ~/apps/checkpoint
git pull
# 3. Image neu bauen und Container ersetzen
cd ~/stacks/checkpoint
docker compose build
docker compose up -d
# 4. Logs prüfen
docker logs checkpoint --tail 50
# 5. App im Browser aufrufen und prüfen
```
---
### Stufe 2 — Python-Code, Routen, Templates (keine DB-Änderung)
**Beispiele:** Bugfix in einer Route, neues Template, geänderte Business-Logik,
neue Blueprint-Route.
**Risiko:** keines für die Daten. Aber: fehlerhafter Code kann die App down bringen.
Lokal testen bevor pushen.
**Vorgehen:** identisch mit Stufe 1.
`db.create_all()` läuft beim Container-Start automatisch — bei unverändertem
Datenmodell macht es nichts.
---
### Stufe 3 — Neue Tabelle oder neue Spalte (additiv)
**Beispiele:** Neues Modell hinzufügen, optionale Spalte ergänzen.
**Risiko:** mittel. `db.create_all()` legt neue Tabellen automatisch an, ändert
aber **bestehende Tabellen nicht**. Neue Spalte vergessen → App crasht beim ersten
Zugriff auf das Feld.
**Vorgehen:**
```bash
# 1. Backup ziehen (und lokal runterkopieren)
docker exec checkpoint python3 -c "import sqlite3; src=sqlite3.connect('/app/instance/checkpoint.sqlite'); dst=sqlite3.connect('/app/instance/latest-backup.sqlite'); src.backup(dst); dst.close(); src.close()"
# 2. Code holen, bauen, starten
cd ~/apps/checkpoint && git pull
cd ~/stacks/checkpoint && docker compose build && docker compose up -d
# 3. Neue Spalte manuell ergänzen (Beispiel)
docker exec -it checkpoint python3 -c "
import sqlite3
con = sqlite3.connect('/app/instance/checkpoint.sqlite')
con.execute('ALTER TABLE user ADD COLUMN telefon TEXT')
con.commit()
con.close()
"
# 4. Logs prüfen
docker logs checkpoint --tail 50
# 5. App testen — besonders die betroffenen Bereiche
```
Neue Tabellen (komplett neue Modelle) werden von `db.create_all()` automatisch
angelegt — kein manueller Schritt nötig.
---
### Stufe 4 — Schema-Änderung an bestehenden Tabellen
**Beispiele:** Spalte umbenennen, Datentyp ändern, Tabelle umstrukturieren,
Spalte löschen.
**Risiko:** hoch. SQLite unterstützt viele `ALTER TABLE`-Operationen nicht nativ.
Niemals ohne Backup und ohne vorherige Absprache durchführen.
**Vorgehen:**
```bash
# 1. Backup ziehen UND lokal runterkopieren (Pflicht)
docker exec checkpoint python3 -c "import sqlite3; src=sqlite3.connect('/app/instance/checkpoint.sqlite'); dst=sqlite3.connect('/app/instance/latest-backup.sqlite'); src.backup(dst); dst.close(); src.close()"
scp patsy@<vps-ip>:/var/lib/docker/volumes/checkpoint_checkpoint_data/_data/latest-backup.sqlite ./checkpoint-backup-$(date +%Y%m%d).sqlite
# 2. Migrationsstrategie mit Claude besprechen bevor Code angefasst wird
# 3. Lokal testen mit einer Kopie der echten DB
# 4. Erst dann: Code holen, bauen, starten
cd ~/apps/checkpoint && git pull
cd ~/stacks/checkpoint && docker compose build && docker compose up -d
# 5. Migration manuell ausführen (Strategie je nach Änderung)
# 6. Intensiv testen
```
**SQLite-Einschränkung:** Spalten umbenennen geht ab SQLite 3.25+, Spalten löschen
ab 3.35+. Datentyp ändern oder komplexe Umstrukturierungen erfordern die
„Tabelle neu bauen"-Strategie:
1. Neue Tabelle mit korrekter Struktur anlegen
2. Daten rüber kopieren
3. Alte Tabelle löschen
4. Neue Tabelle umbenennen
Bei Stufe 4 immer erst besprechen, nie blind durchführen.
---
## Update-Checkliste (für jedes Update)
```
Vor dem Update
□ Backup manuell ausgelöst
□ Backup-Datei im Volume vorhanden (ls -lh prüfen)
□ Bei Stufe 3/4: Backup lokal runtergeladen
Update
□ git pull
□ docker compose build
□ docker compose up -d
Nach dem Update
□ docker logs checkpoint --tail 50 — keine Fehler?
□ App im Browser aufgerufen — lädt sie?
□ Login funktioniert?
□ Bei Stufe 3: ALTER TABLE ausgeführt?
□ Betroffene Funktion manuell getestet?
```
---
## Rollback (wenn etwas schiefgeht)
```bash
# 1. Letzten funktionierenden Commit finden
cd ~/apps/checkpoint
git log --oneline -10
# 2. Auf diesen Commit zurückgehen
git checkout <commit-hash>
# 3. Image neu bauen und starten
cd ~/stacks/checkpoint
docker compose build
docker compose up -d
# 4. Bei DB-Schaden: Backup wiederherstellen
docker exec checkpoint python3 -c "
import sqlite3
src = sqlite3.connect('/app/instance/latest-backup.sqlite')
dst = sqlite3.connect('/app/instance/checkpoint.sqlite')
src.backup(dst)
dst.close()
src.close()
"
```
---
## Drei Backup-Ebenen im Überblick
| Ebene | Was | Wie oft | Wo |
|---|---|---|---|
| 1 | Manuell vor jedem Update | Bei jedem Update | Docker Volume (VPS) |
| 2 | Automatischer Cronjob | Täglich 03:30 UTC | Docker Volume (VPS) |
| 3 | Lokale Kopie | Mindestens wöchentlich | Eigener Rechner |
Ebene 3 ist die wichtigste — nur ein Backup außerhalb des VPS ist ein echtes Backup.