Files
tessera-ctl/.gitea/scripts/image-start-check.sh
T
schalli bf632d90a5 fix(quick-261009-p0m): Review-Befunde WR-01/02/04/05, IN-01/02/03/04 (Abbild-Bau, Semgrep im Container, Zeitbudget, ZAP-Haken)
- WR-01: prisma generate als eigener Schritt mit Pruefung im api-Abbild, Bau scheitert ohne Client; Startprobe als .gitea/scripts/image-start-check.sh versioniert
- WR-02: Semgrep im offiziellen Container, per Digest angepinnt (kein pipx/PyPI mehr)
- WR-04: Zeitbudget 1500 s, Limits je Werkzeug, Ergebniszeile sofort nach jedem Werkzeug
- WR-05: Authorization-Ersetzung der ZAP-Pruefung nur fuer das Ziel
- IN-01: yarn/npm per Platzhalter entfernt und Abwesenheit geprueft (api und web)
- IN-02: Kommentar zu doppelten Kopfzeilen in next.config.ts richtiggestellt
- IN-03: Berichtsordner Modus 700, Zugangsdaten nur als base64 (keine curl-Konfiguration)
- IN-04: flacher Klon wird bei gitleaks als unvollstaendig gemeldet

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-09 20:59:12 +02:00

87 lines
3.6 KiB
Bash
Executable File

#!/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"