taskmanager/REGISTRY.md
Weapie 7be231409f
All checks were successful
check / verify (push) Successful in 3m10s
check / publish (push) Has been skipped
Fail early when Gitea advertises an insecure registry token endpoint
2026-10-08 08:45:52 +02:00

7.2 KiB

Docker-Registry und Releases

Registry: git.jfritzsche.de, Eigentümer: jf.

Verwendung Image Tags eines Releases v1.0.0
Webanwendung git.jfritzsche.de/jf/taskmanager 1.0.0, latest
Datenmigration und Worker git.jfritzsche.de/jf/taskmanager-operations 1.0.0, latest

Beide Images sind erforderlich. Das kleine Web-Image enthält absichtlich keine Migrationswerkzeuge. Veröffentlichte Architektur: linux/amd64. ARM64 ist derzeit kein veröffentlichtes Ziel.

Automatische Veröffentlichung

.github/workflows/check.yml wird vom vorhandenen Gitea-Runner verarbeitet. Bei Push und Pull Request laufen Typecheck, Lint, Runtime-Audit, Sicherheits-/Integrationstests, die Migration vom Altschema, Produktionsbuild und Browsertests. Prüfjob und PostgreSQL-Services teilen ein Container-Netz; Verbindung über postgres:5432 statt Container-Loopback. Die Upgrade-Probe verwendet einen getrennten Datenbank-Service, ohne Docker-Zugriff aus dem Prüfjob.

Nur ein gepushter stabiler Git-Tag vX.Y.Z, der exakt zur Version in package.json passt, startet nach erfolgreichen Prüfungen den Veröffentlichungsjob. Branches, Pull Requests und Vorabversionen aktualisieren latest nicht. Bereits vorhandene Versions-Tags werden vor dem Build geprüft und nicht bewusst überschrieben. Veröffentlichungen nacheinander ausführen; alte Release-Tags nicht erneut veröffentlichen. latest bezeichnet das zuletzt erfolgreich veröffentlichte stabile Release, keinen Entwicklungsbranch.

Zuerst werden beide Versionsimages veröffentlicht. Erst wenn beide Pushes erfolgreich waren, werden die latest-Tags gesetzt. Registry-Updates zweier Images sind nicht atomar; bei einem Abbruch während dieses letzten Schritts können die Aliase kurz unterschiedliche Versionen bezeichnen. Produktion deshalb mit gleicher expliziter Versionsnummer für alle drei Dienste betreiben.

Registry-Anmeldung für Actions

Der Veröffentlichungsjob braucht einen Runner mit Docker/Buildx und HTTPS-Zugriff auf die Registry. Für Gitea 1.22.3 einen eigenen Access-Token des Benutzers jf mit write:package verwenden und im Repository unter Einstellungen → Actions → Secrets speichern:

  • REGISTRY_TOKEN: eingeschränkter Paket-Token, kein Administratorpasswort.
  • REGISTRY_USERNAME: optional, Standard ist der Repository-Eigentümer jf.

Ein bereits vorhandenes Secret bleibt unverändert. Der Workflow kann alternativ den eingebauten GITEA_TOKEN verwenden, sofern die eingesetzte Gitea-Version dessen Paketveröffentlichung unterstützt. permissions: packages: write allein rüstet diese Fähigkeit älterer Server nicht nach. Secrets nie in Git, Build-Argumenten oder Logs speichern. Das operations-Image erhält durch .dockerignore weder lokale .env noch Backups oder Uploads.

Gitea-Pakete gehören einem Benutzer/einer Organisation. Sichtbarkeit nach dem ersten Publish prüfen und Pakete bei Bedarf mit jf/taskmanager verknüpfen. Private Images erfordern beim Deployment einen separaten Token mit read:package. Dokumentation: Gitea Container Registry.

Gitea hinter einem HTTPS-Proxy

Gitea muss seine externe URL kennen. In app.ini:

[server]
ROOT_URL = https://git.jfritzsche.de/

Alternativ im Gitea-Container GITEA__server__ROOT_URL=https://git.jfritzsche.de/ setzen und Gitea neu starten. Der interne Listener darf weiterhin HTTP auf Port 3000 verwenden. HTTPS am Proxy allein korrigiert nicht automatisch die Registry-Token-URL.

Bei einer geänderten Compose-Umgebungsvariable reicht docker restart nicht: den Gitea-Dienst aus dessen eigenem Compose-Projekt neu erstellen (docker compose up -d --force-recreate DIENSTNAME). Das ist nicht der Taskmanager-Dienst. In der Gitea-Administrationsansicht die tatsächlich geladene Serverkonfiguration prüfen; eine Umgebungsvariable kann eine manuell bearbeitete app.ini beim Start wieder überschreiben. Keine Secrets oder vollständigen Umgebungsvariablen in Fehlerlogs veröffentlichen.

Neue Release-Workflows prüfen den HTTPS-Realm bereits vor Login und Image-Build mit node scripts/check-registry.mjs. Ein erneuter Lauf des alten Tags v1.0.0 verwendet weiterhin den Workflow dieses Tags; die Serverkorrektur ist auch dafür erforderlich.

curl -sS -D - -o /dev/null https://git.jfritzsche.de/v2/

Ohne Anmeldung ist HTTP 401 normal. Der WWW-Authenticate-Header muss als Bearer-Realm https://git.jfritzsche.de/v2/token nennen. Ein HTTP-Realm kann den Upload mit authorization server did not include a token in the response scheitern lassen, obwohl docker login erfolgreich erschien. Keine HTTP-/TLS-Ausnahmen als Ersatz einrichten. Nach Korrektur den fehlgeschlagenen publish-Job erneut starten; dafür weder einen Release-Tag verschieben noch die Anwendung neu versionieren.

Neues Release erstellen

# Geprüften Release-Stand auschecken, keine uncommitteten Änderungen.
npm version 1.0.1 --no-git-tag-version
git add package.json package-lock.json
git commit -m "Release 1.0.1"
git push origin HEAD
git tag -a v1.0.1 -m "Release 1.0.1"
git push origin v1.0.1

Workflow-Erfolg und beide Registry-Images prüfen. Tags nicht verschieben. Bei teilweise veröffentlichtem Release die fehlenden Schritte gezielt reparieren oder eine neue Version verwenden; kein Force-Push eines anderen Images auf eine bestehende Version.

Deployment ohne lokalen Image-Build

Docker Compose mindestens 2.24.4 wegen !reset. Checkout/Compose-Dateien müssen zum Image-Release passen. Die Upgrade- und Backup-Anleitung gilt unverändert: bei vorhandenen Daten zuerst UPGRADE.md, insbesondere keine Neuinitialisierung.

docker login git.jfritzsche.de --username jf
# Passwort-Prompt: Token mit read:package, nicht im Befehl ausschreiben.
export TASKMANAGER_VERSION=1.0.0
docker compose -p taskmanager -f docker-compose.yml -f docker-compose.registry.yml pull
docker compose -p taskmanager -f docker-compose.yml -f docker-compose.registry.yml up -d --wait db
docker compose -p taskmanager -f docker-compose.yml -f docker-compose.registry.yml run --rm migrate
# Nur leere Neuinstallation: einmaliges Bootstrap nach README.
docker compose -p taskmanager -f docker-compose.yml -f docker-compose.registry.yml up -d --wait app worker

docker-compose.registry.yml ersetzt alle Build-Definitionen durch Registry-Images. Volumes, private Anhänge, Healthchecks, Sicherheitsoptionen und Migrationsreihenfolge aus dem Basis-Compose bleiben erhalten. Den tatsächlichen Projektnamen verwenden; ein anderer Name kann leere neue Volumes erzeugen. Auch bei Backup-/Restore-Befehlen dieselben Compose-Dateien und denselben Projektnamen verwenden.

Zum Nachschlagen verfügbar, für geplante Upgrades aber die konkrete Version bevorzugen:

docker pull git.jfritzsche.de/jf/taskmanager:latest
docker pull git.jfritzsche.de/jf/taskmanager-operations:latest
docker buildx imagetools inspect git.jfritzsche.de/jf/taskmanager:1.0.0
docker buildx imagetools inspect git.jfritzsche.de/jf/taskmanager-operations:1.0.0

Kein automatischer Austausch der laufenden Produktivinstallation: Veröffentlichung und produktives Upgrade sind getrennte Schritte. Ein älteres Image allein macht Datenbankmigrationen nicht rückgängig.