Phase 5: Gitea Actions, Betriebs-Compose und README

Ein Versions-Tag (v*) löst den Bau aus, ein Push auf main nicht - so bleibt
das Zusammenführen von Branches folgenlos und ein Release ist ein bewusster
Schritt. Die CI baut, testet das FERTIGE Image und veröffentlicht erst
danach; "latest" nur bei echten Tags.

Beim Durchspielen des Prüfschritts zwei Fehler gefunden, die beide erst in
der CI aufgefallen wären - und einer davon gar nicht:

1. "docker exec" ohne -i hängt kein stdin an. Das Here-Dokument lief damit
   ins Leere, python bekam ein leeres Programm, tat nichts und meldete
   Erfolg. Ein Test, der nie hätte fehlschlagen können. Lokal nachgestellt
   und mit -i behoben.
2. Die YAML war ungültig: eingebettete Python-Blöcke standen links vom
   Einzug und brachen den run-Block auf. Das Prüfskript liegt jetzt als
   scripts/image-pruefen.py vor - dadurch lässt es sich auch lokal gegen
   ein gebautes Image laufen lassen - und die Warteschleife ist einzeilig.

Aus der Kantone-App übernommen: github.ref_name geht über env in die
Shell statt direkt als Ausdruck (Tag-Namen dürfen " und $ enthalten, und
der Job hält ein Registry-Token), Anmeldung per --password-stdin, docker
logout mit if: always(), Rechte auf contents:read und packages:write.

docker-compose.betrieb.yml liefert bewusst KEIN Passwort mit: ohne eigenes
bleibt der Erfassungsbereich gesperrt. Genau das war die schwerste Lücke
der Kantone-App.

Ausserdem fehlte eine .dockerignore - der ganze Kontext samt .git und .env
ging an den Docker-Daemon, obwohl das Dockerfile nur gezielt kopiert.

81 Tests grün, der CI-Prüfschritt lokal gegen das gebaute Image
durchgespielt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GR4bNaj9GtRu57J4Niii8o
This commit is contained in:
2026-08-30 08:40:57 +02:00
co-authored by Claude Opus 5
parent adedaa9a0d
commit 31f59fd3c8
6 changed files with 487 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
# Was nicht in den Build-Kontext gehört.
#
# Das Dockerfile kopiert ohnehin nur gezielt einzelne Verzeichnisse, es
# landet also nichts davon im Image. Aber der gesamte Kontext wird an den
# Docker-Daemon übertragen - und .env enthält das Admin-Passwort.
.env
.git
.gitea
.github
.claude
# Laufzeitdaten (im Betrieb Volumes)
data/
uploads/
*.sqlite
*.sqlite3
# Entwicklung
tests/
.pytest_cache/
.venv/
venv/
__pycache__/
*.py[cod]
# Wird im Build erzeugt bzw. nur dort gebraucht
tailwindcss
Plan.md
projekt.md
README.md