Goal: at every session start, run exactly the application the repo says — and be able to move to a new upstream release deliberately, with a way back. The old setup (v1-latest + pull_policy: always) was unreliable in both directions. `docker compose up -d` silently pulled a new application, including an irreversible SurrealDB schema migration, while a reboot (restart: always) or `docker compose start` kept running the old image without pulling anything. The running version was effectively unpredictable. Note v1-latest tracks releases, not main: the current image (v1.10.0, 2026-06-18) IS the latest release — the repo being "ahead" is unreleased code, which is explicitly not wanted here. So this is about guaranteeing and detecting, not catching up. - docker-compose.yml: both images pinned by digest, pull_policy: missing. - scripts/check_updates.sh: reports running version/digest vs the latest release and registry digest. Changes nothing; meant for the session-start ritual. - scripts/update_stack.sh: resolve new digest -> stop -> back up surreal_data, notebook_data and docker-compose.yml -> repin -> start -> smoke test -> roll back data AND compose file if the smoke test fails. The data backup is the point: the app migrates the DB on startup and an older app cannot read a migrated DB, so a bad update would otherwise be a one-way door. tar runs inside a container because the data dirs are root-owned and the host user cannot restore over them. - scripts/smoke_test.sh: checks what actually breaks here, not just "does it start". Every local adaptation leans on upstream internals and can break silently: the prompts/podcast directory mount masks the image's directory (a new template upstream would be invisible), config/content_core.yaml freezes content-core's defaults (because CCORE_CONFIG_PATH replaces rather than merges), and the env-var workarounds depend on current content-core/esperanto/podcast_creator behaviour. So it verifies those assumptions explicitly, plus API, TTS audio, STT and a real YouTube transcript. Both scripts read the digest from the lfnovo/open_notebook line specifically. A naive "first sha256 in the file" grep matches surrealdb (listed first) — caught while testing: check_updates.sh falsely reported an update, and update_stack.sh would have rewritten the database image instead of the application. Verified: smoke test green against the current stack, and red (exit 1) when failures are injected (dead TTS port, removed template variable). Backup/restore mechanics exercised separately: 44 MB in 3.3s, restore yields 13 DB files and 91 notebook files. The update path itself cannot be exercised end to end until a newer image exists. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
57 lines
2 KiB
Bash
Executable file
57 lines
2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Zeigt, ob es ein neues Open-Notebook-Release gibt. Aendert NICHTS.
|
|
#
|
|
# Gedacht fuer den Sitzungsstart: Du siehst, worauf du laeufst und ob etwas Neues da
|
|
# ist — und entscheidest selbst, wann du migrierst (./scripts/update_stack.sh).
|
|
# Bewusst kein Auto-Update: ein Image-Update migriert die Datenbank und kann unsere
|
|
# Anpassungen brechen (siehe scripts/smoke_test.sh).
|
|
set -uo pipefail
|
|
|
|
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$REPO"
|
|
|
|
TAG="lfnovo/open_notebook:v1-latest"
|
|
|
|
# Gezielt aus der open_notebook-Zeile: ein blindes grep auf den ersten Digest der Datei
|
|
# erwischt surrealdb (steht weiter oben) und vergleicht dann Aepfel mit Birnen.
|
|
pinned="$(grep -oP 'lfnovo/open_notebook\S*@\Ksha256:[0-9a-f]+' docker-compose.yml | head -1)"
|
|
running_ver="$(docker compose exec -T open_notebook grep -m1 '^version' /app/pyproject.toml 2>/dev/null |
|
|
grep -oP '(?<=")[^"]+' || echo '?')"
|
|
|
|
echo "Laeuft gerade"
|
|
echo " Version : ${running_ver}"
|
|
echo " Digest : ${pinned:-(nicht gepinnt!)}"
|
|
|
|
echo
|
|
echo "Verfuegbar"
|
|
latest_rel="$(curl -sf -m 10 https://api.github.com/repos/lfnovo/open-notebook/releases/latest |
|
|
python3 -c "import json,sys;d=json.load(sys.stdin);print(d['tag_name'],'vom',d['published_at'][:10])" 2>/dev/null)"
|
|
echo " Release : ${latest_rel:-(GitHub nicht erreichbar)}"
|
|
|
|
remote="$(docker buildx imagetools inspect "$TAG" --format '{{.Manifest.Digest}}' 2>/dev/null)"
|
|
if [ -z "$remote" ]; then
|
|
echo " Image : (Registry nicht erreichbar)"
|
|
exit 0
|
|
fi
|
|
echo " Image : $remote"
|
|
|
|
echo
|
|
if [ "$remote" = "$pinned" ]; then
|
|
echo "Du laeufst auf dem aktuellen Release. Nichts zu tun."
|
|
exit 0
|
|
fi
|
|
|
|
cat <<EOF
|
|
NEUES IMAGE VERFUEGBAR.
|
|
|
|
gepinnt : $pinned
|
|
neu : $remote
|
|
|
|
Update mit Backup, Rauchtest und Rollback:
|
|
./scripts/update_stack.sh
|
|
|
|
Vorher lohnt ein Blick in die Release-Notes — vor allem auf Aenderungen an den
|
|
Podcast-Vorlagen, an content-core und an der Datenbank:
|
|
https://github.com/lfnovo/open-notebook/releases
|
|
EOF
|
|
exit 0
|