#!/usr/bin/env bash # image-start-check.sh -- Startprobe fuer das Server-Abbild (quick-261009-p0m). # # Beweist, dass das fertig gebaute api-Abbild (ohne Entwicklungswerkzeuge) gegen eine # FRISCHE, leere Datenbank alle Migrationen anwendet und die API startet. Das faengt # genau den Fehler ab, den ein Bau allein nicht zeigt: ein Abbild, dem der Prisma-Client # oder ein Laufzeitpaket fehlt, wird gebaut und veroeffentlicht, stirbt aber beim Start. # # Aufruf (aus dem Repository-Wurzelverzeichnis, Docker noetig): # bash .gitea/scripts/image-start-check.sh # lokales Abbild tessera-ctl-api:latest # bash .gitea/scripts/image-start-check.sh localhost:3002/schalli/tessera-ctl/api:beta # # Es startet ein kurzlebiges Postgres 16 und das Abbild in einem eigenen Docker-Netz, mit # reinen Testwerten (keine echten Zugangsdaten, kein Zugriff auf Tessera oder alpha). # Alles Angelegte wird beim Beenden wieder entfernt. Bei Erfolg endet die Ausgabe mit # "frische-datenbank ok" und Exit 0, sonst mit einer Fehlermeldung, dem Ende des # API-Protokolls und Exit 1. Wird nicht automatisch von der Pipeline aufgerufen; es # gehoert in die Freigabe-Checkliste (docs/anleitung-betrieb.md, docs/anleitung-entwicklung.md). set -u IMAGE="${1:-tessera-ctl-api:latest}" ID="start-check-$$" NET="$ID-net" DB="$ID-db" API="$ID-api" LOG="$(mktemp)" cleanup() { docker rm -f "$API" "$DB" >/dev/null 2>&1 docker network rm "$NET" >/dev/null 2>&1 rm -f "$LOG" } trap cleanup EXIT INT TERM HUP PIPE fail() { echo "FEHLER: $*" >&2 echo "--- Protokoll der API (letzte 40 Zeilen) ---" >&2 docker logs "$API" 2>&1 | tail -40 >&2 exit 1 } docker network create "$NET" >/dev/null || { echo "FEHLER: Netz nicht anlegbar" >&2; exit 1; } docker run -d --name "$DB" --network "$NET" \ -e POSTGRES_USER=tessera -e POSTGRES_PASSWORD=tessera_test -e POSTGRES_DB=tessera \ postgres:16-alpine >/dev/null || { echo "FEHLER: Datenbank startet nicht" >&2; exit 1; } i=0 until docker exec "$DB" pg_isready -U tessera -d tessera >/dev/null 2>&1; do i=$((i + 1)) [ "$i" -gt 60 ] && { echo "FEHLER: Datenbank wird nicht bereit" >&2; exit 1; } sleep 1 done # pg_isready meldet schon waehrend der Einrichtung "bereit"; kurz warten, dann # eine echte Abfrage (die Einrichtung startet den Server einmal neu). sleep 3 i=0 until docker exec "$DB" psql -U tessera -d tessera -tAc 'select 1' >/dev/null 2>&1; do i=$((i + 1)) [ "$i" -gt 30 ] && { echo "FEHLER: Datenbank antwortet nicht" >&2; exit 1; } sleep 1 done KEY="$(head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n')" docker run -d --name "$API" --network "$NET" \ -e "DATABASE_URL=postgresql://tessera:tessera_test@$DB:5432/tessera" \ -e "TESSERA_ENCRYPTION_KEY=$KEY" \ -e "JWT_SECRET=fresh-db-test-jwt-secret" \ -e TESSERA_ADMIN_USER=admin -e TESSERA_ADMIN_EMAIL=admin@tessera.local \ -e TESSERA_ADMIN_PASSWORD=fresh-db-test-pw -e TESSERA_FORCE_CHANGE=false \ "$IMAGE" >/dev/null || { echo "FEHLER: API startet nicht" >&2; exit 1; } i=0 while :; do docker logs "$API" >"$LOG" 2>&1 grep -q "Tessera API running" "$LOG" && break [ "$(docker inspect -f '{{.State.Running}}' "$API" 2>/dev/null)" = "true" ] || fail "Container ist beendet, bevor die Startzeile kam" i=$((i + 1)) [ "$i" -gt 120 ] && fail "keine Startzeile nach 120 Sekunden" sleep 1 done grep -qi "successfully applied" "$LOG" || fail "Prisma meldet nicht, dass die Migrationen angewendet wurden" N="$(docker exec "$DB" psql -U tessera -d tessera -tAc "select count(*) from _prisma_migrations where finished_at is not null")" [ "${N:-0}" -ge 1 ] || fail "keine abgeschlossene Migration in der Datenbank" echo "migrationen=$N" echo "frische-datenbank ok"