Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9603917a86 | ||
|
|
42eb242767 |
@@ -47,6 +47,10 @@ AUTH_TRUST_HOST=true
|
||||
APP_BIND=127.0.0.1
|
||||
APP_PORT=3000
|
||||
|
||||
# Die Konsole des mitgelieferten Objektspeichers. Nur noetig, wenn auf dem
|
||||
# Server schon etwas auf 9001 laeuft.
|
||||
MINIO_KONSOLE_PORT=9001
|
||||
|
||||
# --- Anwendungsseitige Feldverschluesselung ---------------------------------
|
||||
# AES-256-GCM. 32 Bytes, base64. OHNE DIESEN SCHLUESSEL SIND DIE VERSCHLUESSELTEN
|
||||
# FELDER UNWIEDERBRINGLICH VERLOREN - unbedingt getrennt vom Backup sichern!
|
||||
|
||||
+43
-1
@@ -26,6 +26,47 @@ Wiederherstellung*.
|
||||
|
||||
_Noch nichts._
|
||||
|
||||
## [1.0.5] – 2026-08-22
|
||||
|
||||
### Hinzugefügt
|
||||
|
||||
- **`scripts/update.sh`** — aktualisiert die Anwendung mit einem Befehl.
|
||||
|
||||
```bash
|
||||
./scripts/update.sh # auf die neueste Fassung
|
||||
./scripts/update.sh --pruefen # nur nachsehen, nichts ändern
|
||||
./scripts/update.sh v1.2.0 # auf eine bestimmte Fassung
|
||||
```
|
||||
|
||||
Es nimmt die Schritte ab, die man von Hand vergisst: Sicherung
|
||||
anstoßen und bei Misserfolg **abbrechen**, den Changelog zwischen altem
|
||||
und neuem Stand anzeigen, umschalten, neu bauen, warten bis die
|
||||
Anwendung antwortet, **die beiden SQL-Skripte ausführen** und zum
|
||||
Schluss prüfen, ob wirklich die neue Fassung läuft.
|
||||
|
||||
Zwei Eigenschaften, die dabei zählen:
|
||||
|
||||
**Bis zur Rückfrage wird nichts verändert.** Bricht etwas vorher ab —
|
||||
Server nicht erreichbar, falsche Versionsangabe — findest du alles so
|
||||
vor wie zuvor. Kein Halbzustand.
|
||||
|
||||
**Eigene Änderungen an versionierten Dateien blockieren nicht.** Im
|
||||
Betrieb passt man die `docker-compose.yml` an, bis etwas läuft; genau
|
||||
diese Anpassungen sind später oft schon eingearbeitet. Das Skript legt
|
||||
sie vor dem Umschalten mit `git stash` beiseite und sagt, wie man sie
|
||||
zurückholt. Mit `--verwerfen` werden sie stattdessen weggeworfen. Die
|
||||
`.env` bleibt immer unangetastet — sie ist nicht versioniert.
|
||||
|
||||
Schlägt der Bau fehl, nennt das Skript den Weg zurück auf den
|
||||
vorherigen Stand.
|
||||
|
||||
### Behoben
|
||||
|
||||
- **Der Port der MinIO-Konsole ließ sich nicht ändern.** Er stand fest auf
|
||||
`9001`; lief dort schon etwas, startete der ganze Stapel nicht
|
||||
(`port is already allocated`). Jetzt über `MINIO_KONSOLE_PORT` in der
|
||||
`.env` einstellbar — dieselbe Möglichkeit, die `APP_PORT` schon hatte.
|
||||
|
||||
## [1.0.4] – 2026-08-22
|
||||
|
||||
### Behoben
|
||||
@@ -351,7 +392,8 @@ Was davon wann angegangen wird, steht in [`docs/ROADMAP.md`](docs/ROADMAP.md).
|
||||
|
||||
---
|
||||
|
||||
[Unveröffentlicht]: https://git.wilde-server.de/florian.wilde/betreuungs-cockpit/compare/v1.0.4...HEAD
|
||||
[Unveröffentlicht]: https://git.wilde-server.de/florian.wilde/betreuungs-cockpit/compare/v1.0.5...HEAD
|
||||
[1.0.5]: https://git.wilde-server.de/florian.wilde/betreuungs-cockpit/compare/v1.0.4...v1.0.5
|
||||
[1.0.4]: https://git.wilde-server.de/florian.wilde/betreuungs-cockpit/compare/v1.0.3...v1.0.4
|
||||
[1.0.3]: https://git.wilde-server.de/florian.wilde/betreuungs-cockpit/compare/v1.0.2...v1.0.3
|
||||
[1.0.2]: https://git.wilde-server.de/florian.wilde/betreuungs-cockpit/compare/v1.0.1...v1.0.2
|
||||
|
||||
@@ -177,12 +177,18 @@ existiert.
|
||||
### Aktualisieren
|
||||
|
||||
```bash
|
||||
git pull
|
||||
docker compose up -d --build
|
||||
./scripts/update.sh
|
||||
```
|
||||
|
||||
Die Migrationen laufen beim Start des Anwendungsbehälters mit. **Vorher ein
|
||||
Backup anstoßen** (siehe unten) — eine Migration lässt sich nicht zurückrollen.
|
||||
Das Skript sichert zuerst, zeigt den Changelog zwischen altem und neuem
|
||||
Stand, fragt nach, schaltet um, baut neu und führt danach die beiden
|
||||
SQL-Skripte aus. Schlägt die Sicherung fehl, wird nicht aktualisiert.
|
||||
|
||||
`--pruefen` sieht nur nach, ohne etwas zu ändern. Eigene Änderungen an
|
||||
versionierten Dateien werden vor dem Umschalten beiseite gelegt
|
||||
(`git stash`), die `.env` bleibt unangetastet.
|
||||
|
||||
Einzelheiten und der Weg von Hand: [`docs/INSTALLATION.md`](docs/INSTALLATION.md).
|
||||
|
||||
---
|
||||
|
||||
|
||||
+5
-2
@@ -66,7 +66,10 @@ services:
|
||||
ports:
|
||||
# Nur an die Loopback-Adresse gebunden. Die Konsole erreichst du
|
||||
# ueber einen SSH-Tunnel oder ueber deinen vorhandenen Proxy.
|
||||
- '127.0.0.1:9001:9001'
|
||||
#
|
||||
# Laeuft auf dem Server schon etwas auf 9001, weich in der .env aus:
|
||||
# MINIO_KONSOLE_PORT=9011
|
||||
- '${MINIO_KONSOLE_BIND:-127.0.0.1}:${MINIO_KONSOLE_PORT:-9001}:9001'
|
||||
networks: [intern]
|
||||
|
||||
app:
|
||||
@@ -93,7 +96,7 @@ services:
|
||||
ENC_KEY_V1: ${ENC_KEY_V1:?ENC_KEY_V1 fehlt in der .env - ohne ihn sind die verschluesselten Felder nicht lesbar}
|
||||
# Bleibt leer, solange nicht rotiert wird. Die Anwendung ueberspringt
|
||||
# leere Schluesselvariablen - siehe src/lib/env.ts.
|
||||
ENC_KEY_V2: ${ENC_KEY_V2:-}
|
||||
# ENC_KEY_V2: ${ENC_KEY_V2:-}
|
||||
ENC_KEY_AKTIV: ${ENC_KEY_AKTIV:-1}
|
||||
INDEX_KEY: ${INDEX_KEY:?INDEX_KEY fehlt in der .env}
|
||||
SESSION_MAX_AGE: ${SESSION_MAX_AGE:-1800}
|
||||
|
||||
+76
-9
@@ -832,27 +832,80 @@ Denk an die letzten Pflichten:
|
||||
|
||||
## Aktualisieren
|
||||
|
||||
```bash
|
||||
cd /opt/betreuungs-cockpit
|
||||
./scripts/update.sh
|
||||
```
|
||||
|
||||
Das war es. Das Skript nimmt dir die Schritte ab, die man von Hand
|
||||
vergisst:
|
||||
|
||||
1. Prüft Verzeichnis, git, docker und `.env`
|
||||
2. Holt die Fassungen und zeigt, was zwischen deinem Stand und dem neuen
|
||||
im Changelog steht
|
||||
3. Fragt nach
|
||||
4. **Stößt eine Sicherung an** — und bricht ab, wenn sie nicht klappt
|
||||
5. Legt eigene Änderungen an versionierten Dateien beiseite, schaltet um,
|
||||
baut neu
|
||||
6. Wartet, bis die Anwendung antwortet
|
||||
7. Führt die **beiden SQL-Skripte** aus (Volltextsuche, Audit-Schutz)
|
||||
8. Prüft, ob wirklich die neue Fassung läuft
|
||||
|
||||
**Bis Schritt 3 wird nichts verändert.** Bricht etwas vorher ab, findest du
|
||||
alles so vor wie zuvor.
|
||||
|
||||
### Aufrufmöglichkeiten
|
||||
|
||||
| Aufruf | Wirkung |
|
||||
|---|---|
|
||||
| `./scripts/update.sh` | auf die neueste veröffentlichte Fassung |
|
||||
| `./scripts/update.sh v1.2.0` | auf eine bestimmte Fassung |
|
||||
| `./scripts/update.sh --pruefen` | nur nachsehen, nichts ändern |
|
||||
| `./scripts/update.sh --ja` | ohne Rückfrage (für cron) |
|
||||
| `./scripts/update.sh --verwerfen` | eigene Änderungen wegwerfen statt beiseitelegen |
|
||||
| `./scripts/update.sh --ohne-sicherung` | Sicherung überspringen — sehr gut überlegen |
|
||||
|
||||
### Eigene Änderungen an der docker-compose.yml
|
||||
|
||||
Das ist der Normalfall: Man passt etwas an, bis es läuft. Das Skript legt
|
||||
solche Änderungen vor dem Umschalten mit `git stash` beiseite und sagt,
|
||||
wie man sie zurückholt:
|
||||
|
||||
```bash
|
||||
git stash list # was liegt da
|
||||
git stash pop # zurückholen
|
||||
git stash drop # wegwerfen
|
||||
```
|
||||
|
||||
Sind deine Anpassungen inzwischen im Projekt eingearbeitet — wie
|
||||
`APP_BIND` oder `MINIO_KONSOLE_PORT` —, brauchst du sie nicht
|
||||
zurückzuholen. Dann setz die Werte einfach in der `.env`.
|
||||
|
||||
> **Die `.env` wird nie angefasst.** Sie ist nicht versioniert; weder
|
||||
> `git checkout` noch das Skript rühren sie an.
|
||||
|
||||
### Von Hand, wenn du lieber selbst steuerst
|
||||
|
||||
```bash
|
||||
cd /opt/betreuungs-cockpit
|
||||
|
||||
# 1. IMMER zuerst sichern - eine Migration lässt sich nicht zurückrollen
|
||||
docker compose exec sicherung /bin/sh /sicherung.sh
|
||||
|
||||
# 2. Was ändert sich? Lies den Changelog, bevor du ziehst
|
||||
# 2. Was ändert sich?
|
||||
git fetch --tags
|
||||
git log --oneline HEAD..origin/main
|
||||
|
||||
# 3. Auf die neue Fassung wechseln
|
||||
# 3. Umschalten
|
||||
git checkout v1.1.0
|
||||
|
||||
# 4. Neu bauen und starten
|
||||
GIT_COMMIT=$(git rev-parse --short HEAD) \
|
||||
BUILD_ZEIT=$(date -Iseconds) \
|
||||
docker compose up -d --build
|
||||
```
|
||||
GIT_COMMIT=$(git rev-parse --short HEAD) BUILD_ZEIT=$(date -Iseconds) docker compose up -d --build
|
||||
|
||||
Die Migrationen laufen beim Start mit. **Sagt der Changelog, dass sich ein
|
||||
SQL-Skript geändert hat, führ die beiden Befehle aus Schritt 5 erneut aus.**
|
||||
# 5. Die beiden SQL-Skripte - sie laufen NICHT mit den Migrationen mit
|
||||
docker compose exec app node node_modules/prisma/build/index.js db execute --schema prisma/schema.prisma --file prisma/sql/volltextsuche.sql
|
||||
docker compose exec app node node_modules/prisma/build/index.js db execute --schema prisma/schema.prisma --file prisma/sql/audit-schutz.sql
|
||||
```
|
||||
|
||||
### Kontrolle
|
||||
|
||||
@@ -862,7 +915,21 @@ curl -s https://cockpit.deine-domain.de/api/gesundheit
|
||||
```
|
||||
|
||||
Steht dort noch die alte Version, läuft der alte Behälter weiter — dann
|
||||
hat der Bau nicht durchgezogen. Sieh in `docker compose logs app`.
|
||||
hat der Bau nicht durchgezogen:
|
||||
|
||||
```bash
|
||||
docker compose up -d --build --force-recreate app
|
||||
```
|
||||
|
||||
### Zurück auf den vorherigen Stand
|
||||
|
||||
```bash
|
||||
git checkout v1.0.4
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Hat die neue Fassung die Datenbank migriert, reicht das nicht — dann muss
|
||||
auch die Sicherung zurück (siehe Schritt 9).
|
||||
|
||||
---
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "betreuungs-cockpit",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"private": true,
|
||||
"description": "Arbeits- und Dokumentationswerkzeug fuer die ehrenamtliche rechtliche Betreuung",
|
||||
"engines": {
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Betreuungs-Cockpit aktualisieren.
|
||||
#
|
||||
# ./scripts/update.sh auf die neueste veroeffentlichte Fassung
|
||||
# ./scripts/update.sh v1.2.0 auf eine bestimmte Fassung
|
||||
# ./scripts/update.sh --ja ohne Rueckfrage (fuer cron)
|
||||
# ./scripts/update.sh --pruefen nur nachsehen, nichts aendern
|
||||
# ./scripts/update.sh --verwerfen eigene Aenderungen an versionierten
|
||||
# Dateien wegwerfen statt beiseitelegen
|
||||
#
|
||||
# Was das Skript tut, in dieser Reihenfolge:
|
||||
#
|
||||
# 1. Voraussetzungen pruefen (Verzeichnis, git, docker, .env)
|
||||
# 2. Fassungen holen und vergleichen
|
||||
# 3. Zeigen, was sich aendert (Changelog-Abschnitte dazwischen)
|
||||
# 4. Nachfragen
|
||||
# 5. SICHERUNG anstossen - und abbrechen, wenn sie nicht klappt
|
||||
# 6. Eigene Aenderungen beiseitelegen, umschalten, neu bauen, starten
|
||||
# 7. Die beiden SQL-Skripte ausfuehren (sie sind idempotent)
|
||||
# 8. Pruefen, ob die neue Fassung wirklich laeuft
|
||||
#
|
||||
# Die Reihenfolge ist Absicht: Bis einschliesslich Schritt 4 wird nichts
|
||||
# veraendert. Wer vorher abbricht - oder wobei etwas schiefgeht -, findet
|
||||
# alles so vor wie zuvor. Erst danach wird angefasst.
|
||||
#
|
||||
# Schritt 5 ist der wichtigste: Eine Datenbank-Migration laesst sich nicht
|
||||
# zurueckrollen. Ohne Sicherung wird hier nichts aktualisiert.
|
||||
#
|
||||
# Schritt 7 ebenfalls: Die SQL-Skripte laufen NICHT mit den Migrationen
|
||||
# mit. Wer sie vergisst, hat einen veralteten Trigger und merkt es erst,
|
||||
# wenn etwas nicht geht.
|
||||
#
|
||||
# Die .env wird nie angefasst - sie ist nicht versioniert.
|
||||
|
||||
# Die geschweiften Klammern sorgen dafuer, dass bash die ganze Datei liest,
|
||||
# bevor sie irgendetwas ausfuehrt. Ohne sie koennte der git-checkout weiter
|
||||
# unten das Skript unter den eigenen Fuessen austauschen.
|
||||
{
|
||||
set -euo pipefail
|
||||
|
||||
# --- Ausgabe -----------------------------------------------------------------
|
||||
|
||||
if [ -t 1 ]; then
|
||||
ROT=$'\033[31m'; GRUEN=$'\033[32m'; GELB=$'\033[33m'; FETT=$'\033[1m'; AUS=$'\033[0m'
|
||||
else
|
||||
ROT=''; GRUEN=''; GELB=''; FETT=''; AUS=''
|
||||
fi
|
||||
|
||||
schritt() { printf '\n%s==> %s%s\n' "$FETT" "$1" "$AUS"; }
|
||||
gut() { printf ' %s%s%s\n' "$GRUEN" "$1" "$AUS"; }
|
||||
warnung() { printf ' %s%s%s\n' "$GELB" "$1" "$AUS"; }
|
||||
abbruch() { printf '\n%sAbbruch: %s%s\n\n' "$ROT" "$1" "$AUS" >&2; exit 1; }
|
||||
|
||||
# --- Aufrufparameter ---------------------------------------------------------
|
||||
|
||||
ZIEL=""
|
||||
OHNE_RUECKFRAGE=0
|
||||
NUR_PRUEFEN=0
|
||||
OHNE_SICHERUNG=0
|
||||
VERWERFEN=0
|
||||
ENTSCHEIDUNG=""
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--ja|-j) OHNE_RUECKFRAGE=1 ;;
|
||||
--pruefen|-p) NUR_PRUEFEN=1 ;;
|
||||
--ohne-sicherung) OHNE_SICHERUNG=1 ;;
|
||||
--verwerfen) VERWERFEN=1 ;;
|
||||
--hilfe|-h)
|
||||
sed -n '2,34p' "$0" | sed 's/^#\s\?//'
|
||||
exit 0 ;;
|
||||
-*) abbruch "Unbekannte Angabe: $arg (--hilfe zeigt die Moeglichkeiten)" ;;
|
||||
*) ZIEL="$arg" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# --- 1. Voraussetzungen ------------------------------------------------------
|
||||
|
||||
schritt "Voraussetzungen"
|
||||
|
||||
cd "$(dirname "$0")/.." || abbruch "Das Projektverzeichnis ist nicht erreichbar."
|
||||
PROJEKT="$(pwd)"
|
||||
|
||||
[ -f docker-compose.yml ] || abbruch "Hier liegt keine docker-compose.yml: $PROJEKT"
|
||||
[ -f .env ] || abbruch "Es gibt keine .env. Ohne sie startet die Anwendung nicht."
|
||||
command -v git >/dev/null || abbruch "git ist nicht installiert."
|
||||
docker compose version >/dev/null 2>&1 || abbruch "docker compose (v2) ist nicht verfuegbar."
|
||||
|
||||
gut "Verzeichnis: $PROJEKT"
|
||||
|
||||
# Nur nachsehen - angefasst wird die Arbeitskopie erst kurz vor dem
|
||||
# Umschalten, wenn Sicherung und Rueckfrage durch sind. Ein Abbruch
|
||||
# dazwischen darf keinen Halbzustand hinterlassen.
|
||||
SCHMUTZIG=""
|
||||
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
|
||||
SCHMUTZIG="ja"
|
||||
warnung "Es gibt eigene Aenderungen an versionierten Dateien."
|
||||
git status --short --untracked-files=no | sed 's/^/ /'
|
||||
printf ' Sie werden vor dem Umschalten beiseite gelegt.\n'
|
||||
else
|
||||
gut "Arbeitskopie ist sauber"
|
||||
fi
|
||||
|
||||
# --- 2. Was ist da, was kommt ------------------------------------------------
|
||||
|
||||
schritt "Fassungen"
|
||||
|
||||
if ! git fetch --tags --quiet origin; then
|
||||
abbruch "Konnte die Fassungen nicht vom Server holen.
|
||||
Erreichst du ihn? Stimmen die Zugangsdaten?
|
||||
Es wurde nichts geaendert."
|
||||
fi
|
||||
|
||||
JETZT="$(git describe --tags --exact-match 2>/dev/null || git rev-parse --short HEAD)"
|
||||
NEUESTE="$(git tag --list 'v*' --sort=-v:refname | head -1)"
|
||||
|
||||
[ -n "$NEUESTE" ] || abbruch "Es gibt keine veroeffentlichte Fassung (kein Tag)."
|
||||
|
||||
if [ -z "$ZIEL" ]; then
|
||||
ZIEL="$NEUESTE"
|
||||
fi
|
||||
|
||||
git rev-parse --verify --quiet "$ZIEL^{commit}" >/dev/null \
|
||||
|| abbruch "Die Fassung '$ZIEL' gibt es nicht. Vorhanden:
|
||||
$(git tag --list 'v*' --sort=-v:refname | head -5 | sed 's/^/ /')"
|
||||
|
||||
printf ' Jetzt: %s\n' "$JETZT"
|
||||
printf ' Ziel: %s%s%s\n' "$FETT" "$ZIEL" "$AUS"
|
||||
|
||||
if [ "$(git rev-parse HEAD)" = "$(git rev-parse "$ZIEL^{commit}")" ]; then
|
||||
gut "Bereits auf dem gewuenschten Stand - nichts zu tun."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --- 3. Was aendert sich -----------------------------------------------------
|
||||
|
||||
schritt "Was sich aendert"
|
||||
|
||||
# Der Changelog muss aus der ZIELfassung kommen: Der laufende Stand kennt
|
||||
# die neuen Abschnitte ja noch gar nicht.
|
||||
CHANGELOG="$(git show "$ZIEL:CHANGELOG.md" 2>/dev/null || true)"
|
||||
|
||||
if [ -n "$CHANGELOG" ]; then
|
||||
# Alle Abschnitte zwischen dem laufenden und dem gewuenschten Stand.
|
||||
JETZT_NR="${JETZT#v}"
|
||||
printf '%s
|
||||
' "$CHANGELOG" | awk -v jetzt="$JETZT_NR" '
|
||||
/^## \[/ {
|
||||
nummer = $0
|
||||
sub(/^## \[/, "", nummer); sub(/\].*/, "", nummer)
|
||||
if (nummer == jetzt) exit
|
||||
drucken = (nummer != "Unveröffentlicht")
|
||||
}
|
||||
drucken { print " " $0 }
|
||||
' | head -60
|
||||
else
|
||||
warnung "Kein CHANGELOG.md in $ZIEL gefunden."
|
||||
fi
|
||||
|
||||
printf '\n'
|
||||
git log --oneline --no-decorate "HEAD..$ZIEL" | head -15 | sed 's/^/ /'
|
||||
|
||||
if [ "$NUR_PRUEFEN" = "1" ]; then
|
||||
printf '\n'
|
||||
gut "Nur geprueft - es wurde nichts geaendert."
|
||||
[ -n "$SCHMUTZIG" ] && warnung "Beim echten Lauf wuerden deine Aenderungen beiseite gelegt."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --- 4. Nachfragen -----------------------------------------------------------
|
||||
|
||||
if [ "$OHNE_RUECKFRAGE" != "1" ]; then
|
||||
printf '\n%sJetzt aktualisieren auf %s? [j/N] %s' "$FETT" "$ZIEL" "$AUS"
|
||||
read -r antwort </dev/tty || antwort=""
|
||||
case "$antwort" in
|
||||
[jJ]|[jJ][aA]) ;;
|
||||
*) printf '\n'; warnung "Abgebrochen, nichts geaendert."; exit 0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# --- 5. Sicherung ------------------------------------------------------------
|
||||
|
||||
if [ "$OHNE_SICHERUNG" = "1" ]; then
|
||||
schritt "Sicherung wird uebersprungen"
|
||||
warnung "Auf eigene Gefahr - eine Migration laesst sich nicht zurueckrollen."
|
||||
else
|
||||
schritt "Sicherung"
|
||||
|
||||
if docker compose ps --status running --services 2>/dev/null | grep -qx sicherung; then
|
||||
if docker compose exec -T sicherung /bin/sh /sicherung.sh; then
|
||||
gut "Sicherung angelegt und selbst geprueft."
|
||||
else
|
||||
abbruch "Die Sicherung ist fehlgeschlagen. Es wird nichts aktualisiert.
|
||||
Mit --ohne-sicherung laesst sich das uebergehen - aber ueberleg
|
||||
dir das zweimal."
|
||||
fi
|
||||
else
|
||||
warnung "Der Dienst 'sicherung' laeuft nicht - es wurde nichts gesichert."
|
||||
if [ "$OHNE_RUECKFRAGE" != "1" ]; then
|
||||
printf '\n %sTrotzdem weitermachen? [j/N] %s' "$FETT" "$AUS"
|
||||
read -r weiter </dev/tty || weiter=""
|
||||
case "$weiter" in [jJ]|[jJ][aA]) ;; *) abbruch "Abgebrochen." ;; esac
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- 6. Umschalten und bauen -------------------------------------------------
|
||||
|
||||
# Aenderungen an versionierten Dateien blockieren das Umschalten.
|
||||
#
|
||||
# Im Betrieb ist das der Normalfall: Man passt die docker-compose.yml an,
|
||||
# bis etwas laeuft. Genau diese Anpassungen sind spaeter oft schon
|
||||
# eingearbeitet - das Skript soll sie also nicht zum Hindernis machen.
|
||||
#
|
||||
# Verworfen wird trotzdem nichts stillschweigend. Standard ist "beiseite
|
||||
# legen": git stash macht es rueckholbar. Wer sie wirklich weghaben will,
|
||||
# nimmt --verwerfen.
|
||||
#
|
||||
# Die .env ist nie betroffen - sie ist nicht versioniert.
|
||||
schritt "Eigene Aenderungen"
|
||||
|
||||
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
|
||||
printf '\n Diese versionierten Dateien sind veraendert:\n\n'
|
||||
git status --short --untracked-files=no | sed 's/^/ /'
|
||||
printf '\n'
|
||||
|
||||
if [ "$VERWERFEN" = "1" ]; then
|
||||
ENTSCHEIDUNG="verwerfen"
|
||||
elif [ "$OHNE_RUECKFRAGE" = "1" ]; then
|
||||
# Ohne jemanden zum Fragen: die sichere Variante.
|
||||
ENTSCHEIDUNG="beiseite"
|
||||
else
|
||||
printf ' %s[b]%s eiseite legen (git stash, spaeter rueckholbar)\n' "$FETT" "$AUS"
|
||||
printf ' %s[v]%s erwerfen (endgueltig weg)\n' "$FETT" "$AUS"
|
||||
printf ' %s[a]%s bbrechen\n\n' "$FETT" "$AUS"
|
||||
printf ' Was soll damit geschehen? [b/v/a] '
|
||||
read -r wahl </dev/tty || wahl=""
|
||||
case "$wahl" in
|
||||
[bB]|'') ENTSCHEIDUNG="beiseite" ;;
|
||||
[vV]) ENTSCHEIDUNG="verwerfen" ;;
|
||||
*) abbruch "Abgebrochen, nichts geaendert." ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ "$ENTSCHEIDUNG" = "verwerfen" ]; then
|
||||
git checkout -- .
|
||||
warnung "Aenderungen verworfen."
|
||||
else
|
||||
STASH_NAME="vor Update $(date +%Y-%m-%d_%H%M)"
|
||||
git stash push --quiet --message "$STASH_NAME" -- . \
|
||||
|| abbruch "Konnte die Aenderungen nicht beiseite legen."
|
||||
gut "Beiseite gelegt als: $STASH_NAME"
|
||||
printf ' Ansehen: git stash list\n'
|
||||
printf ' Zurueck: git stash pop\n'
|
||||
printf ' Wegwerfen: git stash drop\n'
|
||||
fi
|
||||
else
|
||||
gut "Arbeitskopie ist sauber"
|
||||
fi
|
||||
|
||||
schritt "Umschalten auf $ZIEL"
|
||||
|
||||
# Eine unversionierte Datei kann im Weg stehen, wenn die Zielfassung sie
|
||||
# fuehrt. Das passiert beim Update auf die Fassung, die dieses Skript
|
||||
# eingefuehrt hat: Man hat es sich von Hand geholt, jetzt gehoert es dazu.
|
||||
# Solche Dateien werden nicht weggeworfen, sondern beiseite geschoben.
|
||||
if ! git checkout --quiet "$ZIEL" 2>/dev/null; then
|
||||
IM_WEG="$(git checkout "$ZIEL" 2>&1 | sed -n '/would be overwritten/,/^Aborting/p' | grep -E '^\s' | tr -d ' ' | grep -v '^$' || true)"
|
||||
|
||||
if [ -n "$IM_WEG" ]; then
|
||||
ZEIT="$(date +%Y%m%d-%H%M%S)"
|
||||
printf ' Diese unversionierten Dateien stehen im Weg:
|
||||
'
|
||||
for datei in $IM_WEG; do
|
||||
[ -e "$datei" ] || continue
|
||||
mv "$datei" "${datei}.vor-update-${ZEIT}"
|
||||
printf ' %s -> %s.vor-update-%s
|
||||
' "$datei" "$datei" "$ZEIT"
|
||||
done
|
||||
git checkout --quiet "$ZIEL" || abbruch "Das Umschalten auf $ZIEL ist fehlgeschlagen.
|
||||
Deine Aenderungen liegen im Stash: git stash list"
|
||||
else
|
||||
abbruch "Das Umschalten auf $ZIEL ist fehlgeschlagen.
|
||||
$([ -n "$SCHMUTZIG" ] && printf ' Deine Aenderungen liegen im Stash: git stash list')"
|
||||
fi
|
||||
fi
|
||||
|
||||
gut "$(git describe --tags --always)"
|
||||
|
||||
schritt "Bauen und starten"
|
||||
printf ' Das dauert beim ersten Mal einige Minuten.\n\n'
|
||||
|
||||
if ! GIT_COMMIT="$(git rev-parse --short HEAD)" \
|
||||
BUILD_ZEIT="$(date -Iseconds)" \
|
||||
docker compose up -d --build; then
|
||||
printf '\n'
|
||||
abbruch "Bauen oder Starten ist fehlgeschlagen.
|
||||
Die Quellen stehen jetzt auf $ZIEL, die Anwendung laeuft aber
|
||||
noch mit dem alten Abbild - oder gar nicht.
|
||||
|
||||
Zurueck auf den vorherigen Stand:
|
||||
git checkout $JETZT && docker compose up -d --build
|
||||
$([ -n "$SCHMUTZIG" ] && printf '\n Deine Aenderungen liegen im Stash: git stash list')"
|
||||
fi
|
||||
|
||||
# --- 7. Warten, bis die Anwendung antwortet ----------------------------------
|
||||
|
||||
schritt "Warten auf die Anwendung"
|
||||
|
||||
# Adresse und Port stehen in der .env - Standard ist die Loopback-Adresse.
|
||||
ADRESSE="$(grep -E '^APP_BIND=' .env | tail -1 | cut -d= -f2- | tr -d '"' || true)"
|
||||
PORT="$(grep -E '^APP_PORT=' .env | tail -1 | cut -d= -f2- | tr -d '"' || true)"
|
||||
[ -n "$ADRESSE" ] || ADRESSE="127.0.0.1"
|
||||
[ -n "$PORT" ] || PORT="3000"
|
||||
# Auf 0.0.0.0 kann man nicht zugreifen - dann ueber die Loopback-Adresse.
|
||||
[ "$ADRESSE" = "0.0.0.0" ] && ADRESSE="127.0.0.1"
|
||||
|
||||
GESUND="http://${ADRESSE}:${PORT}/api/gesundheit"
|
||||
ANTWORT=""
|
||||
|
||||
for _ in $(seq 1 60); do
|
||||
ANTWORT="$(curl -fsS --max-time 5 "$GESUND" 2>/dev/null || true)"
|
||||
case "$ANTWORT" in *'"bereit"'*) break ;; esac
|
||||
printf '.'
|
||||
sleep 3
|
||||
done
|
||||
printf '\n'
|
||||
|
||||
case "$ANTWORT" in
|
||||
*'"bereit"'*) gut "Die Anwendung antwortet." ;;
|
||||
*)
|
||||
printf '\n'
|
||||
docker compose logs app --tail 40 | sed 's/^/ /'
|
||||
abbruch "Die Anwendung antwortet nicht unter $GESUND.
|
||||
Die letzten Zeilen aus dem Log stehen oben.
|
||||
Zurueck geht es mit: git checkout $JETZT && docker compose up -d --build"
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- 8. SQL-Skripte ----------------------------------------------------------
|
||||
|
||||
schritt "Volltextsuche und Audit-Schutz"
|
||||
printf ' Diese beiden laufen nicht mit den Migrationen mit.\n'
|
||||
printf ' Sie sind idempotent - mehrfaches Ausfuehren schadet nicht.\n\n'
|
||||
|
||||
PRISMA="node node_modules/prisma/build/index.js"
|
||||
|
||||
for skript in volltextsuche audit-schutz; do
|
||||
if docker compose exec -T app $PRISMA db execute \
|
||||
--schema prisma/schema.prisma --file "prisma/sql/${skript}.sql" >/dev/null 2>&1; then
|
||||
gut "${skript}.sql ausgefuehrt"
|
||||
else
|
||||
warnung "${skript}.sql ist fehlgeschlagen - bitte von Hand nachholen:"
|
||||
printf ' docker compose exec app %s db execute \\\n' "$PRISMA"
|
||||
printf ' --schema prisma/schema.prisma --file prisma/sql/%s.sql\n' "$skript"
|
||||
fi
|
||||
done
|
||||
|
||||
# --- 9. Nachschau ------------------------------------------------------------
|
||||
|
||||
schritt "Ergebnis"
|
||||
|
||||
LAEUFT="$(printf '%s' "$ANTWORT" | sed -n 's/.*"version":"\([^"]*\)".*/\1/p')"
|
||||
ERWARTET="${ZIEL#v}"
|
||||
|
||||
printf ' Erwartet: %s\n' "$ERWARTET"
|
||||
printf ' Laeuft: %s\n' "${LAEUFT:-unbekannt}"
|
||||
|
||||
if [ "$LAEUFT" = "$ERWARTET" ]; then
|
||||
printf '\n'
|
||||
gut "Fertig. Version $ERWARTET laeuft."
|
||||
else
|
||||
printf '\n'
|
||||
warnung "Die laufende Fassung stimmt nicht mit der erwarteten ueberein."
|
||||
warnung "Vermutlich hat der Bau den alten Behaelter stehen lassen:"
|
||||
printf ' docker compose up -d --build --force-recreate app\n'
|
||||
fi
|
||||
|
||||
printf '\n Zustand: docker compose ps\n'
|
||||
printf ' Log: docker compose logs app --tail 50\n'
|
||||
printf ' Zurueck: git checkout %s && docker compose up -d --build\n\n' "$JETZT"
|
||||
|
||||
exit 0
|
||||
}
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
/** Muss zur "version" in der package.json passen. */
|
||||
export const VERSION = '1.0.4'
|
||||
export const VERSION = '1.0.5'
|
||||
|
||||
/**
|
||||
* Kurzer Git-Stand, beim Bauen hineingereicht:
|
||||
|
||||
Reference in New Issue
Block a user