6.9 KiB
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
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:
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:
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:
# 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:
# 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:
# 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:
- Neue Tabelle mit korrekter Struktur anlegen
- Daten rüber kopieren
- Alte Tabelle löschen
- 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)
# 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.