Anleitung · Update
PraxisZeit aktualisieren
So bringen Sie eine bestehende Docker- oder Native-Installation auf eine neue Version — ohne Datenverlust. Datenbank-Migrationen laufen bei jedem Start automatisch.
Immer zuerst
- Backup ziehen (Datenbank + Konfiguration) — siehe je Variante unten. §16 ArbZG: Zeitdaten 2 Jahre aufbewahren.
- Update auf 1.20.0: Die Migration
073_work_blocksübernimmt die Arbeitszeit-Fenster als Arbeitszeit-Blöcke und entfernt die alten Fenster-Spalten — zurück auf 1.19.x geht es nur über dieses Backup. Was nach dem Update zu prüfen ist, steht in UPDATE.md (Abschnitt „Update auf 1.20.0“). - Update auf 1.23.0: Sicherungen sind ab 1.23.0 signiert (mit dem
SECRET_KEYder Installation). Sicherungen von vor 1.23.0 – auch die, die Sie direkt vor dem Update ziehen, solange noch die alte Version läuft – spielenpraxiszeit-server.py restore,restore-backup.batundrestore.shnur mit dem Zusatz--force-unverifiedein – nur mit Dateien der eigenen Installation. Sicherungen sind nicht verschlüsselt: Kopien außer Haus verschlüsselt ablegen und denSECRET_KEYgetrennt aufbewahren (BACKUP.md). - Nach dem Update Browser-Hard-Refresh (
Strg+F5bzw.Cmd+Shift+R) — sonst lädt der Browser das alte Frontend aus dem Cache.
Docker
Die Daten liegen im Docker-Volume postgres_data und bleiben über Updates erhalten (down/up löscht sie nicht — nur down -v würde das Volume entfernen).
1. Backup im Ordner der laufenden (alten) Installation — die Datei dort aufheben (gzip, mit --clean --if-exists — so spielen es restore.sh und der Rollback in UPDATE.md wieder ein; die Variablen aus der .env sind nur im Container gesetzt, daher die festen Namen praxiszeit):
docker compose exec -T db pg_dump -U praxiszeit --clean --if-exists praxiszeit | gzip > backup-$(date +%F).sql.gz
2. Neues Docker-Paket (praxiszeit-<neu>-docker.tar.gz/.zip) herunterladen und entpacken. Es entpackt in einen neuen Ordner praxiszeit-<neu>. Docker Compose leitet den Projektnamen — und damit das Datenbank-Volume — aus dem Ordnernamen ab, solange in der .env kein COMPOSE_PROJECT_NAME steht. Ohne diesen Eintrag startet der neue Ordner mit einer neuen, leeren Datenbank. Deshalb den alten Projektnamen übernehmen, die bestehende .env kopieren (NICHT generate-secrets.sh erneut ausführen) und den alten Stack vorher anhalten:
ALT=/pfad/zur/alten/installation
NEU=/pfad/zum/neuen/praxiszeit-<neu>
PROJEKT="$(cd "$ALT" && docker compose config | sed -n 's/^name: //p')"
docker volume ls | grep "${PROJEKT}_postgres_data" # muss eine Zeile zeigen – sonst hier aufhören
(cd "$ALT" && docker compose down) # OHNE -v
cd "$NEU" && cp "$ALT/.env" .env
grep -q '^COMPOSE_PROJECT_NAME=' .env || echo "COMPOSE_PROJECT_NAME=${PROJEKT}" >> .env
grep -nE '^(SECRET_KEY|ADMIN_PASSWORD)=(<|BITTE_AENDERN|CHANGE_ME)' .env # muss LEER bleiben (ab 1.20.3)
docker compose pull db # PostgreSQL-18-Patchstand (`up` zieht ihn nie neu)
docker compose build --pull # frische Basis-Images (Sicherheitsupdates)
docker compose -f docker-compose.yml -f docker-compose.ssl.yml up -d
docker compose exec -T db psql -U praxiszeit -d praxiszeit -tAc 'SELECT count(*) FROM users'Zeigt die Zählung nur 1 (den Initial-Admin), lief der Stack gegen ein leeres Volume: docker compose down (ohne -v), COMPOSE_PROJECT_NAME auf das richtige <projekt>_postgres_data korrigieren und neu starten. Neue Installationen ab 1.20.1 tragen COMPOSE_PROJECT_NAME=praxiszeit bereits in der .env.
Ab 1.20.3 startet das Backend nicht mehr mit Vorlagenwerten. Zeigt die grep-Zeile oben einen Treffer, den Wert vor dem up ersetzen. Einen neuen SECRET_KEY erzeugt python3 -c "import secrets; print(secrets.token_hex(64))" (alle Sitzungen werden dabei abgemeldet).
Eigene Anpassungen an docker-compose.yml (z. B. ein anderer Port als 80) stehen im neuen Paket wieder auf dem Auslieferungsstand — die Anwendung lauscht dann still wieder auf Port 80. Vor dem up übernehmen oder dauerhaft in eine eigene docker-compose.override.yml legen (Compose liest sie automatisch mit, beim Update mitkopieren). Ports dort mit !override angeben, sonst ergänzt Compose die Ports der Grunddatei und bindet weiter Port 80 (Docker Compose ≥ 2.24):
services:
frontend:
ports: !override
- "8095:80"Den alten Paket-Ordner nicht mehr starten: Mit übereinstimmendem Projektnamen nutzt ein docker compose up dort dieselben Volumes und startet die alte Version gegen die bereits aktualisierte Datenbank. Nach erfolgreichem Update löschen oder umbenennen.
Migrationen laufen beim Backend-Start automatisch (docker compose logs backend).
Native — Linux / macOS
Update = das neue Tarball entpacken und den Installer erneut in dasselbe Verzeichnis ausführen. Daten (data/db) und Konfiguration (config/ inkl. .secret-key/.db-credentials/license.key) bleiben erhalten.
# Backup: frischer Dump direkt vor dem Update (Dienst läuft dabei), landet in data/backups/ # macOS: sudo -u _praxiszeit /usr/local/praxiszeit/bin/python/bin/python3 /usr/local/praxiszeit/praxiszeit-server.py backup sudo -u praxiszeit /opt/praxiszeit/bin/python/bin/python3 /opt/praxiszeit/praxiszeit-server.py backup sudo ls /opt/praxiszeit/data/backups/ # der neue Dump liegt hier (data/ ist ab 1.20.2 nur fürs Dienstkonto lesbar) sudo systemctl stop praxiszeit # macOS: launchctl unload (s. INSTALL-NATIVE.md) mkdir -p praxiszeit-<neu> tar xzf praxiszeit-<neu>-linux-x64.tar.gz -C praxiszeit-<neu> # macOS: -macos-x64 / -macos-arm64 cd praxiszeit-<neu> sudo ./install.sh # erkennt die Installation, behält Daten/Config/Lizenz sudo systemctl status praxiszeit
Wichtig: config/ niemals vorher löschen — dort liegen .secret-key und .db-credentials(sonst Session-/DB-Verlust).
Native — Windows
Neues praxiszeit-<neu>-windows-x64.zip entpacken, dann als Administrator:
update-wizard.bat
Der Wizard stoppt den Dienst, spielt Code + Python-Abhängigkeiten ein, installiert bei Bedarf die VC++-Runtime nach und startet den Dienst neu. Konfiguration und Datenbank bleiben erhalten. Seit 1.23.0 lädt der Assistent nichts mehr aus dem Internet; fremde Dateien unter bin\ oder app\, Verknüpfungen und Dateien mit mehreren harten Links sperren das Update (die im Update-Protokoll aufgelisteten Einträge entfernen und erneut ausführen). Stolperfallen: NATIVE-WINDOWS-PITFALLS.md .
Ab 1.20.2 setzen Setup, Update-Assistent und jeder Dienststart die Rechte des Installationsordners fest: normale Windows-Konten dürfen dort nur noch lesen, data\, logs\ und config\ sind für sie gesperrt. Befehle wie praxiszeit-server.py backup oder ein Blick in die Logs brauchen deshalb eine Eingabeaufforderung als Administrator.
Update-Hinweis in der App
Als Admin sehen Sie im Dashboard ein Update-Banner, sobald eine neue Version verfügbar ist. Es informiert nur — eingespielt wird das Update über die oben beschriebenen Schritte. Einen automatischen Schema-Downgrade gibt es nicht; daher vor jedem Update das Backup.
Vollständige Update-Doku auf GitHub
Schritt-für-Schritt inklusive Rollback, Versionsprüfung und plattformspezifischer Details.