monitor/docker-compose.yml
fds2610-bot 6d199f8530 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>
2026-07-28 23:29:40 +02:00

90 lines
3.7 KiB
YAML

services:
api:
build:
context: ./api
dockerfile: docker/Dockerfile
volumes:
- ./api:/app
# Optional: echte status.txt aus der Produktion zum Testen einbinden, z.B.
# - ./status.txt:/status.txt:ro
working_dir: /app
# Achtung: Eine Aenderung des Host-Ports muss in .env (MONITOR_API_BASE) nachgezogen
# werden - das Frontend laeuft im Browser und erreicht die API nicht ueber das
# Compose-Netzwerk, sondern ueber genau diesen Port.
ports:
- "8091:8080"
environment:
MONITOR_DB_PATH: /app/data/monitor.sqlite
MONITOR_ADMIN_API_KEY: ${MONITOR_ADMIN_API_KEY:-dev-admin-key}
MONITOR_STATUS_FILE: /status.txt
MONITOR_DESK_COUNT: 8
MONITOR_SSE_MAX_ITERATIONS: 30
MONITOR_SSE_POLL_INTERVAL: 2
CODEBERG_API_BASE: https://codeberg.org/api/v1
CODEBERG_OWNER: ${CODEBERG_OWNER:-fds2610}
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:
image: nginx:alpine
volumes:
- ./html:/usr/share/nginx/html:ro
# Ueberlagert den Platzhalter html/API.md - der muss existieren, weil in
# einem read-only gemounteten Verzeichnis kein Mountpoint angelegt werden kann.
- ./API.md:/usr/share/nginx/html/API.md:ro
# Setzt office.html als Einstiegsseite (sonst 403 auf der Basis-URL) und liefert
# /config.js aus. Als Template gemountet, damit das nginx-Image beim Start
# MONITOR_API_BASE per envsubst einsetzt (Ausgabe: /etc/nginx/conf.d/default.conf).
- ./docker/nginx/default.conf.template:/etc/nginx/templates/default.conf.template:ro
environment:
# Wird in docker/nginx/default.conf.template eingesetzt und als /config.js an den
# Browser ausgeliefert. Leer = gleicher Origin (relatives /api/v1).
MONITOR_API_BASE: ${MONITOR_API_BASE:-}
ports:
- "8090:80"
# Fuehrt die Node-basierten Frontend-Tests (tests/frontend/) aus. Node/npm sind nur im
# Container noetig, nicht auf dem Host (analog zum api-Service mit PHP/Composer).
frontend:
image: node:20-alpine
working_dir: /app
volumes:
- .:/app
command: npm test