Codeberg-Sync als Dauerlaeufer statt manuellem Aufruf

Auf der Produktion blieb das Kanban-Board leer, obwohl die API lief und der
registrierte Agent angezeigt wurde: Tickets entstehen nur aus Agenten-Meldungen
oder aus bin/sync-codeberg.php, und das Skript war zwar als "per Cron oder
manuell" dokumentiert, wurde aber nirgends automatisch ausgefuehrt.

Neuer Compose-Service "sync": nutzt Image, Volume und SQLite-Datei des
api-Service, macht sofort beim Start einen Lauf und wiederholt ihn alle
MONITOR_SYNC_INTERVAL Sekunden (Default 600). Ein fehlgeschlagener Lauf bricht
die Schleife nicht ab, damit ein Codeberg-Ausfall keinen Restart-Loop ausloest.
Der Service verbindet sich ausschliesslich ausgehend nach codeberg.org und
braucht daher kein Port-Mapping - in Produktion sind weder Proxy- noch
Firewall-Freigaben noetig.

update.sh startet den Dienst mit, die Doku beschreibt den Service statt des
Cron-Hinweises; der manuelle Aufruf bleibt als Debug-Weg dokumentiert, weil dort
die Klartext-Fehler des Codeberg-Clients sichtbar werden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
fds2610-bot 2026-07-28 23:29:40 +02:00
parent ba52522415
commit 6d199f8530
6 changed files with 72 additions and 9 deletions

View file

@ -14,5 +14,10 @@ MONITOR_API_BASE=http://localhost:8091/api/v1
# Codeberg-Repo, aus dem Backlog/Done per Sync-Skript befuellt werden
CODEBERG_OWNER=fds2610
CODEBERG_REPO=monitor
# Optional: Token mit Lesezugriff, falls Rate-Limits ohne Token zu knapp sind
# Optional: Token mit Lesezugriff, falls Rate-Limits ohne Token zu knapp sind - bei kleinem
# MONITOR_SYNC_INTERVAL (haeufigem Sync) empfehlenswert
CODEBERG_TOKEN=
# Abstand zwischen zwei Codeberg-Sync-Laeufen in Sekunden (Service "sync" in
# docker-compose.yml). Der erste Lauf passiert direkt beim Start des Services.
MONITOR_SYNC_INTERVAL=600

23
API.md
View file

@ -235,16 +235,31 @@ schliessen.
## Codeberg-Sync (Backlog/Done)
`api/bin/sync-codeberg.php` (per Cron oder manuell auszufuehren) liest offene und
geschlossene Issues aus dem konfigurierten Codeberg-Repo (`CODEBERG_OWNER`/`CODEBERG_REPO`)
und gleicht sie ueber `external_ref` (= Issue-Nummer) mit den Tickets ab:
`api/bin/sync-codeberg.php` liest offene und geschlossene Issues aus dem konfigurierten
Codeberg-Repo (`CODEBERG_OWNER`/`CODEBERG_REPO`) und gleicht sie ueber `external_ref`
(= Issue-Nummer) mit den Tickets ab:
- Offene Issues → Spalte `backlog` (nur falls das Ticket noch in `backlog`/`done` ist -
manuell auf dem Board bewegte Tickets werden nicht zurueckgesetzt).
- Geschlossene Issues → Spalte `done`.
- Ticket-Typ/-Farbe kommen vom ersten Issue-Label (Name/Farbe).
Aufruf via Docker: `docker compose run --rm api php bin/sync-codeberg.php`.
Ausgefuehrt wird das Skript vom Compose-Service `sync` (siehe
[docker-compose.yml](docker-compose.yml)) - kein Host-Cron noetig. Der Service startet mit
dem Stack, macht sofort einen ersten Lauf und wiederholt ihn dann alle
`MONITOR_SYNC_INTERVAL` Sekunden (Default 600, siehe `.env.example`). Er nutzt dasselbe
Image und dieselbe SQLite-Datei wie `api` und verbindet sich ausschliesslich ausgehend nach
codeberg.org - es ist also kein Port-Mapping und keine Firewall-Freigabe noetig.
```bash
docker compose up -d sync # Sync-Service starten
docker compose logs -f sync # Laeufe mitlesen
docker compose run --rm api php bin/sync-codeberg.php # einmalig manuell (Debug)
```
Beim manuellen Aufruf werden Fehler direkt auf der Konsole sichtbar (`Codeberg-API nicht
erreichbar: …` bzw. `Codeberg-API-Fehler (HTTP 4xx)`) - der erste Anlaufpunkt, wenn Backlog
und Done leer bleiben.
## Fehlerformat

View file

@ -21,6 +21,9 @@ die dazugehörigen Klärungen in [Detailfragen.md](Detailfragen.md) und
siehe Visualization.md Abschnitt 9). Ist die API nicht erreichbar, zeigt die Szene
ersatzweise Demo-Daten — kenntlich gemacht durch einen roten Banner „API nicht erreichbar!".
Die Basis-URL der API kommt aus `MONITOR_API_BASE` (siehe `.env.example`).
- Codeberg-Sync als Dauerläufer (Compose-Service `sync`): füllt Backlog und Done automatisch
alle `MONITOR_SYNC_INTERVAL` Sekunden aus den Issues des konfigurierten Codeberg-Repos
(siehe [API.md](API.md) Abschnitt „Codeberg-Sync")
- Weiterhin: klassische Ping-Überwachung (`check_fds.sh`, `hosts.conf`, `mail_fds.py`) als
eine Datenquelle für den System-Monitor; die alte tabellarische Statusseite ist mit
Phase 7 entfallen (F16), `status.txt` speist weiterhin den System-Monitor
@ -49,9 +52,10 @@ Docker-Compose-Containern; auf dem Host muss nichts installiert werden.
```bash
cp .env.example .env # einmalig, MONITOR_ADMIN_API_KEY anpassen
docker compose up --build # API auf :8091, Buero-Visualisierung auf :8090
docker compose up --build # API auf :8091, Buero-Visualisierung auf :8090, Sync
docker compose run --rm api composer test # PHPUnit (API)
docker compose run --rm frontend # Node-Tests (Frontend-Layoutlogik)
docker compose logs -f sync # Codeberg-Sync mitlesen
```
Der Browser erreicht die API nicht über das Compose-Netzwerk, sondern über die in

View file

@ -14,9 +14,13 @@ cp .env.example .env # einmalig, MONITOR_ADMIN_API_KEY anpassen
docker compose up --build # startet die API auf http://localhost:8080
docker compose run --rm api composer test # PHPUnit inkl. Coverage
docker compose run --rm api php bin/sync-codeberg.php # Backlog/Done aus Codeberg ziehen
docker compose run --rm api php bin/sync-codeberg.php # Backlog/Done einmalig ziehen (Debug)
```
Im laufenden Betrieb wird der Codeberg-Sync nicht manuell angestossen, sondern vom
Compose-Service `sync` alle `MONITOR_SYNC_INTERVAL` Sekunden ausgefuehrt (siehe
[../API.md](../API.md), Abschnitt "Codeberg-Sync").
Composer-Abhaengigkeiten (nur PHPUnit als Dev-Dependency) werden beim ersten Start
automatisch **im Container** installiert (`docker/entrypoint.sh`) - auf dem Host ist
weder PHP noch Composer noch SQLite erforderlich.

View file

@ -25,6 +25,41 @@ services:
CODEBERG_REPO: ${CODEBERG_REPO:-monitor}
CODEBERG_TOKEN: ${CODEBERG_TOKEN:-}
# Haelt Backlog/Done aus Codeberg aktuell (F4, siehe API.md Abschnitt "Codeberg-Sync"):
# laeuft dasselbe Image wie api, teilt sich ueber das ./api-Volume dieselbe SQLite-Datei
# und ruft bin/sync-codeberg.php in einer Endlosschleife auf. Ohne diesen Service bleibt
# das Board leer, solange kein Agent selbst Tickets meldet.
# Rein ausgehende Verbindungen (nach codeberg.org), kein Port-Mapping - in Produktion sind
# also weder Proxy- noch Firewall-Freigaben noetig.
sync:
build:
context: ./api
dockerfile: docker/Dockerfile
volumes:
- ./api:/app
working_dir: /app
restart: unless-stopped
depends_on:
- api
environment:
MONITOR_DB_PATH: /app/data/monitor.sqlite
MONITOR_SYNC_INTERVAL: ${MONITOR_SYNC_INTERVAL:-600}
CODEBERG_API_BASE: https://codeberg.org/api/v1
CODEBERG_OWNER: ${CODEBERG_OWNER:-fds2610}
CODEBERG_REPO: ${CODEBERG_REPO:-monitor}
CODEBERG_TOKEN: ${CODEBERG_TOKEN:-}
# "$$" ist ein maskiertes "$" - die Variable soll die Shell im Container aufloesen, nicht
# Compose. Ein fehlgeschlagener Lauf (Codeberg nicht erreichbar, Rate-Limit) darf die
# Schleife nicht beenden, sonst landet der Service in einer Restart-Schleife.
command:
- sh
- -c
- |
while true; do
php bin/sync-codeberg.php || echo "[sync] Lauf fehlgeschlagen, naechster Versuch in $${MONITOR_SYNC_INTERVAL}s"
sleep "$$MONITOR_SYNC_INTERVAL"
done
# Statisches Frontend (html/) - Phase 2 der Neuausrichtung (Buero-Visualisierung).
# Nur zur lokalen Ansicht/Entwicklung, kein Build-Schritt noetig (Vanilla HTML/CSS/JS).
web:

View file

@ -58,8 +58,8 @@ $DOCKER_COMPOSE run --rm api composer install --no-interaction --no-progress
log "Baue Docker-Images neu (falls Dockerfile/Abhaengigkeiten sich geaendert haben)..."
$DOCKER_COMPOSE build
log "Starte Dienste neu (api, web)..."
$DOCKER_COMPOSE up -d api web
log "Starte Dienste neu (api, web, sync)..."
$DOCKER_COMPOSE up -d api web sync
if [ "$UPDATE_RUN_TESTS" = "1" ]; then
log "Fuehre PHPUnit-Tests (API) aus..."