From 43c6a926a2292e40637a4470d0d2a7cc0dbd997a Mon Sep 17 00:00:00 2001 From: TeamVis Release Date: Sat, 10 Oct 2026 23:58:56 +0200 Subject: [PATCH] TeamVis Self-Host-Bundle v0.56.3 --- README.md | 4 +- deploy/selfhost/update.sh | 80 +++++++++++++++++++++++++++------------ package.json | 2 +- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 2dddd8d..b4de1fe 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# TeamVis — Self-Hosting-Bundle (v0.56.2) +# TeamVis — Self-Hosting-Bundle (v0.56.3) Dieses Bundle enthält alles zum **Betreiben** von TeamVis auf eigener Infrastruktur — **keinen** App-Quellcode. Die App selbst kommt als fertiges @@ -36,4 +36,4 @@ Vollständige Schritt-für-Schritt-Anleitung (von der nackten VM bis live): | `supabase/migrations/` | Datenbank-Schema (DDL) | | `docs/` | Anleitungen | -Stand: TeamVis 0.56.2. +Stand: TeamVis 0.56.3. diff --git a/deploy/selfhost/update.sh b/deploy/selfhost/update.sh index de5dc9e..32ee5e3 100755 --- a/deploy/selfhost/update.sh +++ b/deploy/selfhost/update.sh @@ -67,32 +67,48 @@ POSTGRES_DB="${POSTGRES_DB:-postgres}" PGPW="$(grep -E '^POSTGRES_PASSWORD=' "$INSTANCE/.env" 2>/dev/null | cut -d= -f2- || true)" dbsql() { ( cd "$INSTANCE" && docker compose exec -T -e PGPASSWORD="$PGPW" db psql -v ON_ERROR_STOP=1 -U supabase_admin -d "$POSTGRES_DB" "$@" ); } -# ── 1. Pre-Update-Backup (nur Modus 2 — lokale DB) ──────────────────── -if [ "$MODE2" = "1" ]; then - head "1) Datenbank-Backup" - ts="$(date +%Y%m%d-%H%M%S)" - dump="$INSTANCE/backup-db-$ts.sql" - # Der Dump enthält alle Personendaten — nur für den Eigentümer lesbar - # anlegen (vorher landete er mit 644 im Instanz-Verzeichnis). - install -m 600 /dev/null "$dump" - if ( cd "$INSTANCE" && docker compose exec -T -e PGPASSWORD="$PGPW" db pg_dump -U supabase_admin "$POSTGRES_DB" ) > "$dump" 2>/dev/null; then - ok "Backup: $dump ($(wc -l < "$dump") Zeilen)" +if [ -n "${TEAMVIS_UPDATE_REEXEC:-}" ]; then + # Zweiter Durchlauf nach dem Selbst-Neustart (siehe Ende von Schritt 2): + # Sicherung und git pull sind schon erledigt. + OLD="$TEAMVIS_UPDATE_OLD" + NEW="$(git rev-parse HEAD)" + ok "Neue Fassung von update.sh übernommen — weiter ab Schritt 3." +else + # ── 1. Pre-Update-Backup (nur Modus 2 — lokale DB) ──────────────────── + if [ "$MODE2" = "1" ]; then + head "1) Datenbank-Backup" + ts="$(date +%Y%m%d-%H%M%S)" + dump="$INSTANCE/backup-db-$ts.sql" + # Der Dump enthält alle Personendaten — nur für den Eigentümer lesbar + # anlegen (vorher landete er mit 644 im Instanz-Verzeichnis). + install -m 600 /dev/null "$dump" + if ( cd "$INSTANCE" && docker compose exec -T -e PGPASSWORD="$PGPW" db pg_dump -U supabase_admin "$POSTGRES_DB" ) > "$dump" 2>/dev/null; then + ok "Backup: $dump ($(wc -l < "$dump") Zeilen)" + else + warn "Backup fehlgeschlagen — trotzdem fortfahren? (Strg-C zum Abbrechen)"; read -r _ || true + fi else - warn "Backup fehlgeschlagen — trotzdem fortfahren? (Strg-C zum Abbrechen)"; read -r _ || true + warn "Externe Supabase (Modus 1): Backup macht dein Supabase-Anbieter. Kein lokaler Dump." fi -else - warn "Externe Supabase (Modus 1): Backup macht dein Supabase-Anbieter. Kein lokaler Dump." -fi -# ── 2. git pull → neue Migrationen/Skripte ──────────────────────────── -head "2) Bundle aktualisieren (git pull)" -OLD="$(git rev-parse HEAD)" -git pull --ff-only origin main || die "git pull fehlgeschlagen (abweichende Branches?). Notfalls: git fetch && git reset --hard origin/main" -NEW="$(git rev-parse HEAD)" -if [ "$OLD" = "$NEW" ]; then - ok "Schon aktuell (keine neuen Commits)." -else - ok "Aktualisiert: ${OLD:0:8} → ${NEW:0:8}" + # ── 2. git pull → neue Migrationen/Skripte ──────────────────────────── + head "2) Bundle aktualisieren (git pull)" + OLD="$(git rev-parse HEAD)" + git pull --ff-only origin main || die "git pull fehlgeschlagen (abweichende Branches?). Notfalls: git fetch && git reset --hard origin/main" + NEW="$(git rev-parse HEAD)" + if [ "$OLD" = "$NEW" ]; then + ok "Schon aktuell (keine neuen Commits)." + else + ok "Aktualisiert: ${OLD:0:8} → ${NEW:0:8}" + fi + + # Hat der Pull update.sh selbst geändert, läuft ab hier die NEUE Fassung + # weiter — sonst griffen Korrekturen am Skript erst beim nächsten Update + # (Okt. 2026: Instanzen mussten update.sh deshalb mehrfach starten). + if [ "$OLD" != "$NEW" ] && ! git diff --quiet "$OLD" "$NEW" -- deploy/selfhost/update.sh; then + say "update.sh wurde mit aktualisiert — die neue Fassung übernimmt." + exec env TEAMVIS_UPDATE_REEXEC=1 TEAMVIS_UPDATE_OLD="$OLD" bash "$BUNDLE/deploy/selfhost/update.sh" "$INSTANCE" + fi fi # ── 3. Fehlende Migrationen einspielen ──────────────────────────────── @@ -149,10 +165,26 @@ fi # ── 4. Neues Image ziehen + Container neu starten ───────────────────── head "4) App aktualisieren" +# Image-Version: Steht in der .env eine feste, ältere Version (frühere +# Installer, oder bewusst gepinnt), zöge `docker compose pull` immer wieder +# dasselbe alte Image — die App bliebe trotz neuer Migrationen stehen (RZHAS, +# 10.10.2026). Daher auf die Version des Bundles heben. `latest` bleibt +# `latest`, eine bewusst neuere Version bleibt unangetastet. +# (Kein `| head` in diesem Skript: head() ist oben als Überschriften-Funktion +# definiert und überdeckt den Befehl — daher grep -m1.) +BUNDLE_VERSION="$(grep -m1 -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$BUNDLE/package.json" | sed 's/.*"\([^"]*\)"$/\1/')" +CUR_VERSION="$(grep -E '^TEAMVIS_VERSION=' "$INSTANCE/.env" 2>/dev/null | cut -d= -f2- || true)" +if [ -n "$CUR_VERSION" ] && [ -n "$BUNDLE_VERSION" ] && [ "$CUR_VERSION" != "latest" ] && [ "$CUR_VERSION" != "$BUNDLE_VERSION" ] \ + && [ "$(printf '%s\n%s\n' "$CUR_VERSION" "$BUNDLE_VERSION" | sort -V | tail -1)" = "$BUNDLE_VERSION" ]; then + sed -i "s/^TEAMVIS_VERSION=.*/TEAMVIS_VERSION=$BUNDLE_VERSION/" "$INSTANCE/.env" + ok "Image-Version in .env: $CUR_VERSION → $BUNDLE_VERSION" +fi +grep -q 'teamvis:\${TEAMVIS_VERSION' "$INSTANCE/docker-compose.yml" \ + || warn "Das App-Image steht fest in docker-compose.yml (ohne \${TEAMVIS_VERSION}) — bitte dort von Hand auf ${BUNDLE_VERSION:-die neue Version} setzen." ( cd "$INSTANCE" && docker compose pull && docker compose up -d ) ok "Container neu gestartet." head "Fertig 🎉" -SITE_URL="$(grep -E '^SITE_URL=|^NEXT_PUBLIC_SITE_URL=' "$INSTANCE/.env" 2>/dev/null | head -1 | cut -d= -f2-)" +SITE_URL="$(grep -m1 -E '^SITE_URL=|^NEXT_PUBLIC_SITE_URL=' "$INSTANCE/.env" 2>/dev/null | cut -d= -f2- || true)" [ -n "$SITE_URL" ] && say " $SITE_URL" say " Bei Problemen Logs prüfen: ( cd $INSTANCE && docker compose logs -f app )" diff --git a/package.json b/package.json index 8cfe10c..b10a5ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "teamvis-selfhost", - "version": "0.56.2", + "version": "0.56.3", "private": true, "description": "Self-Hosting-Bundle für TeamVis (Installer + Migrationen, ohne App-Quellcode).", "type": "module",