18 KiB
Integrationsplan: Metabase & Teamup → DokuWiki (All-Inkl)
1. Zielbild
Automatisierter Ablauf jeden 1. des Monats um 03:00 Uhr:
- Gitea Action startet ein Shell-Skript auf Hobbybackend1.
- Skript erzeugt:
- einen Metabase-PDF-Export einer Registerkarte (Dashboard/Frage),
- zwei Teamup-Kalenderübersichten als Bilder (jeweils eine Woche, über Datum definiert).
- Skript überträgt PDF/Bilder per SSH/SCP auf den All-Inkl-Server ins DokuWiki-Dateisystem.
- Skript erzeugt oder aktualisiert eine DokuWiki-Seite für das Monatsmeeting, welche die neuen Dateien referenziert.
Verantwortlichkeiten
- Owner / Betrieb:
it@hobbyhimmel.de(Ansprechpartner für Ausfälle, Secrets & Deploy) - Maintainer (Skripte / Runner): Hobbybackend1-Admin (Repository-Owner)
- DokuWiki-Admin: Wiki-Administrator (z. B. für API-Zugriff und Namespace-Setup)
Hinweis: Für dieses Hobbyprojekt genügt eine schlanke Aufgabenverteilung — Owner ist primärer Kontakt für Störungen.
2. Architektur & Datenfluss
-
Gitea (Repository + Actions)
- Enthält:
- Shell-Skript(e)
- ggf. Hilfsskripte (z. B. Node/Puppeteer-Renderer)
- GitHub-/Gitea-Action Workflow
- Trigger:
schedule→ monatlich.
- Enthält:
-
Hobbybackend1 (Docker-Host)
- Stack:
metabase- Container:
metabase-metabase-1
- Container:
- Führt das Shell-Skript aus (über Gitea Action Runner).
- Headless-Browser (z. B. Puppeteer / Playwright in Docker oder lokal installiert) rendert:
- Metabase-Registerkarte export siehe https://www.metabase.com/docs/latest/api
- Teamup-Ansichten export siehe https://apidocs.teamup.com/docs/api/
- Stack:
-
All-Inkl-Server (DokuWiki)
- Per SSH erreichbar.
- Skript überträgt Dateien (
scp/rsync) nachdata/media/.... - Skript erzeugt/aktualisiert
data/pages/...mit DokuWiki-Seite für das entsprechende Monatsmeeting.
3. Voraussetzungen
3.1. Infrastruktur
-
Gitea
- Repository für das Skript (z. B.
hobbyhimmel/teammeeting-dokuwiki). - Gitea Action Runner auf Hobbybackend1 konfiguriert.
- Repository für das Skript (z. B.
-
Hobbybackend1
- Zugriff auf Metabase-Container
metabase-metabase-1. - Node.js + Puppeteer/Playwright oder ein Docker-Image, das URLs per Headless-Browser in PDF/PNG rendert.
- Netzwerkzugriff auf:
- Metabase-URL (intern, z. B.
http://metabase-metabase-1:3000oder über Hostname). - Teamup-URLs.
- Metabase-URL (intern, z. B.
- Zugriff auf Metabase-Container
-
All-Inkl / DokuWiki
- SSH-Zugang: User + SSH-Key (passwortlos aus Skript verwendbar).
- Kenntnis der DokuWiki-Verzeichnisse (typischerweise):
- Seiten:
.../data/pages/... - Medien:
.../data/media/...
- Seiten:
- Namespace für Meetings, z. B.
:teammeetings:folien:.
3.2. Gitea-Secrets
In Gitea als Repository-Secrets hinterlegen (Bezeichnungen Beispiel):
-
Metabase
METABASE_URL– Basis-URL (intern von Hobbybackend1 aus erreichbar).METABASE_USER– Benutzer für Login.METABASE_PASSWORD– Passwort oder API-Key (je nach Login-Strategie).- Optional:
METABASE_DASHBOARD_IDoderMETABASE_CARD_ID.
-
Teamup
TEAMUP_BASE_URL– Basis-URL zum Kalender (inkl. Calendar-Key).- Optional:
TEAMUP_API_KEY– falls API genutzt wird.
-
DokuWiki / All-Inkl
ALLINKL_SSH_HOST– z. B.sshXXX.all-inkl.com.ALLINKL_SSH_USER– SSH-User.ALLINKL_USER– All-Inkl-User.ALLINKL_SSH_KEY– privater SSH-Key (optional; häufig nicht nötig, wenn die DokuWiki-API verwendet wird). Wenn verwendet: als secret file oder String in Kombination mitssh-agent.ALLINKL_BASE_PATH– Pfad zum DokuWiki, z. B./www/htdocs/<ALLINKL_USER>/wiki.neu.hobbyhimmel.de/data.ALLINKL_MEETING_NAMESPACE– z. B.teammeetings/folien(Dateipfade ohne Doppelpunkt).- Optional (bei API-Nutzung):
DOKUWIKI_API_URLundDOKUWIKI_API_TOKEN(empfohlen statt direktem Dateizugriff)
-
Allgemein
TZ– Zeitzone (z. B.Europe/Berlin), falls im Skript nötig.
Hinweis zur Secret-Handhabung:
- Für lokale Tests nutze eine
.env-Datei (niemals einchecken). Beispiele stehen im Repo in einer.env.example(nur Platzhalter). - In Gitea die Secrets als Repository-Secrets anlegen. Verwende
DOKUWIKI_API_TOKENfalls die API genutzt wird;ALLINKL_SSH_KEYwird nur beim Fallback über SSH benötigt.
4. Shell-Skript-Design
4.1. Hauptaufgaben des Skripts
-
Datum & Kontext bestimmen
- Ausführungsdatum ist immer der 1. des Monats.
- Skript ermittelt:
YEAR– aktuelles Jahr.MONTH– aktueller Monat (ggf. auch vorheriger Monat, je nach Reporting-Logik).
- Generiert z. B. einen Identifier
MEETING_ID="${YEAR}-${MONTH}".
-
Export Metabase
- Aufruf eines Hilfsskripts (z. B.
render_metabase.shoder Node-Skript):- Parameter: Dashboard-ID / Card-ID, Dateiname, ggf. Filter (z. B. Zeitraum).
- Ausgabe:
metabase-report-${MEETING_ID}.???im lokalen Arbeitsverzeichnis.
- Aufruf eines Hilfsskripts (z. B.
-
Export Teamup → Kalenderbilder
-
Definition der zwei Wochen, die exportiert werden sollen:
- Es werden immer die ersten zwei Wochen des aktuellen Monats genommen.
-
Für jede Woche:
- URL zu Teamup generieren (inkl.
startDate,endDateoder ähnlichen Parametern). - Ausgabe:
teamup-week1-${MEETING_ID}.png,teamup-week2-${MEETING_ID}.png.
- URL zu Teamup generieren (inkl.
-
-
Transfer zum All-Inkl-Server
- Medienpfad bestimmen, z. B.:
MEDIA_DIR="${ALLINKL_BASE_PATH}/data/media/${TEAM_MEETING_NAMESPACE}" - Falls nicht existent: per
sshOrdner anlegen. - Dateien per
scpoderrsync -e sshkopieren:metabase-report-${MEETING_ID}.pdfteamup-week1-${MEETING_ID}.pngteamup-week2-${MEETING_ID}.png.
- Medienpfad bestimmen, z. B.:
-
DokuWiki-Seite erzeugen/aktualisieren
- Seitenpfad bestimmen, z. B.:
PAGE_FILE="${WIKI_BASE_PATH}/data/pages/${WIKI_MEETING_NAMESPACE}/${MEETING_ID}.txt" - Per
sshRemote-Here-Doc schreiben: Empfehlung: Wenn möglich die DokuWiki-API (DOKUWIKI_API_URL+DOKUWIKI_API_TOKEN) verwenden, statt direkt aufdata/pageszu schreiben. API-Aufrufe sind robuster gegenüber Dateirechten/Ownership auf All-Inkl.
Beispiel (API, einfaches PUT via curl an ein Plugin / XML-RPC-Endpoint - anpassen je nach Wiki-Setup):
curl -sS -X POST "${DOKUWIKI_API_URL}" \ -H "Authorization: Bearer ${DOKUWIKI_API_TOKEN}" \ -F "id=${WIKI_MEETING_NAMESPACE}:${MEETING_ID}" \ -F "text=$(cat newpage.txt)"Fallback (wenn API nicht möglich): per SSH/Here-Doc wie bisher. Achte hier auf korrekte Ownership/Encoding beim Schreiben nach
data/pages.Platzhalter
<DATUM_A>und<DATUM_B>werden im Shell-Skript vor dem Upload ersetzt. - Seitenpfad bestimmen, z. B.:
4.2. Schnittstellen zum Headless-Browser
-
Generische Hilfsfunktionen, z. B.:
render_metabase_pdf() { local url="$1" # z. B. "$METABASE_URL/dashboard/${METABASE_DASHBOARD_ID}?date=${MEETING_ID}" local outfile="$2" node scripts/render_pdf.js "$url" "$outfile" } render_url_to_png() { local url="$1" local outfile="$2" node scripts/render_png.js "$url" "$outfile" } -
render_pdf.js/render_png.jsverwenden Puppeteer/Playwright, loggen sich ggf. bei Metabase ein und erzeugen die Dateien.
5. Gitea Action: Workflow-Definition
5.1. Workflow-Datei .gitea/workflows/monthly-report.yml
name: Monthly Metabase & Teamup Export
on:
schedule:
- cron: '0 2 1 * *'
workflow_dispatch:
jobs:
export-and-upload:
runs-on: hobbybackend1 # Label des Act-Runners
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: |
npm ci
- name: Run export script
env:
METABASE_URL: ${{ secrets.METABASE_URL }}
METABASE_USER: ${{ secrets.METABASE_USER }}
METABASE_PASSWORD: ${{ secrets.METABASE_PASSWORD }}
METABASE_DASHBOARD_ID: ${{ secrets.METABASE_DASHBOARD_ID }}
TEAMUP_BASE_URL: ${{ secrets.TEAMUP_BASE_URL }}
TEAMUP_API_KEY: ${{ secrets.TEAMUP_API_KEY }}
WIKI_SSH_HOST: ${{ secrets.WIKI_SSH_HOST }}
WIKI_SSH_USER: ${{ secrets.WIKI_SSH_USER }}
WIKI_SSH_KEY: ${{ secrets.WIKI_SSH_KEY }}
WIKI_BASE_PATH: ${{ secrets.WIKI_BASE_PATH }}
WIKI_MEETING_NAMESPACE: ${{ secrets.WIKI_MEETING_NAMESPACE }}
TZ: Europe/Berlin
run: |
mkdir -p ~/.ssh
echo "$WIKI_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan "$WIKI_SSH_HOST" >> ~/.ssh/known_hosts
./scripts/monthly_export.sh
Hinweis zur Zeit:
- Gitea/Aktions-Cron läuft typischerweise in UTC.
- Wenn du 03:00 Uhr Europe/Berlin willst, musst du den
cron-Wert ggf. anpassen (Sommer-/Winterzeit beachten). Beispiel oben0 2 1 * *wäre 03:00 MEZ, aber 04:00 MESZ – hier vorher genau prüfen.
6. Teamup: Wochenansichten als Bild
6.1. URL-Strategie
-
Teamup erlaubt üblicherweise Links mit Datumsparametern, z. B.:
?view=week&date=YYYY-MM-DDfür eine Wochenansicht.
-
Das Skript berechnet:
WEEK1_DATE– ISO-Datum (Montag der ersten gewünschten Woche).WEEK2_DATE– ISO-Datum (Montag der zweiten gewünschten Woche).
-
Für jede Woche wird eine URL gebaut:
TEAMUP_URL_WEEK1="${TEAMUP_BASE_URL}?view=week&date=${WEEK1_DATE}" TEAMUP_URL_WEEK2="${TEAMUP_BASE_URL}?view=week&date=${WEEK2_DATE}"
6.2. Rendering
-
Aufruf z. B.:
render_url_to_png "$TEAMUP_URL_WEEK1" "teamup-week1-${MEETING_ID}.png" render_url_to_png "$TEAMUP_URL_WEEK2" "teamup-week2-${MEETING_ID}.png" -
Im Headless-Browser-Skript wird:
- Seite geladen.
- Auf ausreichende Ladezeit gewartet.
page.screenshot({ path: outfile, fullPage: true })ausgeführt.
7. Test- & Rollout-Plan
-
Lokaler Test des Headless-Browsers
- Auf Hobbybackend1 die Node-Skripte (
render_pdf.js/render_png.js) mit Test-URLs ausprobieren. - verifizieren, dass Metabase-Login und Teamup-Laden funktionieren.
- Auf Hobbybackend1 die Node-Skripte (
-
SSH/Dateipfade testen
- Manuell per
sshundscpeine Test-PDF und Test-PNG ins DokuWikidata/mediaübertragen. - testweise eine Seite unter
data/pagesanlegen und im Browser prüfen.
- Manuell per
-
Shell-Skript
monthly_export.shlokal laufen lassen- Mit Test-Umgebungsvariablen (ohne Gitea) ausführen.
- Prüfen, ob alle Schritte durchlaufen und Dateien in DokuWiki korrekt landen.
-
Gitea Action mit
workflow_dispatch- Workflow manuell starten, Log-Ausgaben prüfen.
- Validieren, dass der Action Runner auf Hobbybackend1 das Skript erfolgreich ausführt.
-
Schedule aktiv beobachten
- Nach dem ersten echten Lauf (1. des Monats) kontrollieren:
- Sind PDF/Bilder generiert?
- Ist die neue DokuWiki-Seite da und korrekt verlinkt?
- Nach dem ersten echten Lauf (1. des Monats) kontrollieren:
-
Feinjustierung
- Falls nötig: Cron-Zeit, Dateinamen, Seitentemplate, Wochenlogik (z. B. „nächste + übernächste Woche“) anpassen.
Akzeptanzkriterien
- Metabase-PDF existiert unter
${MEDIA_DIR}/metabase-report-${MEETING_ID}.pdfund Dateigröße > 50 KB. - Zwei Teamup-PNGs existieren unter
${MEDIA_DIR}und sind in der erzeugten DokuWiki-Seite verlinkt. - DokuWiki-Seite
${WIKI_MEETING_NAMESPACE}:${MEETING_ID}ist im Wiki sichtbar und referenziert die Medien. - Action-Log zeigt Exit-Code 0; bei Fehlern wird ein Fehler-Log-Eintrag erzeugt und an
it@hobbyhimmel.degemeldet (oder als Issue im Repo dokumentiert).
Diese Kriterien sind bewusst minimal gehalten und reichen für den Hobbybetrieb eines Vereins aus.
8. Erweiterungen (optional)
- Mehrere Metabase-Registerkarten / Dashboards pro Meeting.
- Automatische Verlinkung aus einer Übersichtsseite (z. B.
:teammeetings:start) auf die neuen Monatsseiten. - Fehlerreport per Mail oder in DokuWiki-Logseite, wenn Exports fehlschlagen.
- Optionale Parameter, um das Skript für „ad hoc Exports“ außerhalb des Monatslaufes zu nutzen (z. B.
./monthly_export.sh 2025-03).
Umsetzung: Lokaler Testplan (Metabase, Teamup, DokuWiki)
Ziel: Die drei beteiligten APIs lokal auf deinem PC (Windows, cmd.exe) testen und verifizieren, dass:
- ein Metabase-Export erzeugt werden kann,
- Teamup-Daten (oder Screenshots der Wochenansicht) erzeugt werden können,
- eine DokuWiki-Seite erstellt/aktualisiert und Medien eingebunden werden können.
Hinweis: Lege lokal eine .env-Datei an (niemals einchecken). Nutze eine .env.example im Repo mit Platzhaltern.
Basic-Prüfwerkzeuge (lokal installieren/prüfen):
curl(Windows 10+ meist vorhanden),jq(hilfreich für JSON-Auswertung),node+npm(falls du Puppeteer/Playwright oder Node-Renderer nutzen willst),- optional
wkhtmltopdf/Headless Chrome für Rendering.
- Metabase — lokaler API-Test
Zweck: Authentifizieren und einen PDF- oder JSON-Export eines Dashboards/Cards abrufen.
Vorgehen:
- Voraussetzungen: Metabase ist von deinem PC aus erreichbar (z. B. via VPN oder Port-Forwarding auf
http://localhost:3000). - Env-Variablen (Beispiel in
.env):METABASE_URL=http://localhost:3000METABASE_USER=...METABASE_PASSWORD=...METABASE_CARD_ID=123(oderMETABASE_DASHBOARD_ID)
Schritte (vereinfachtes Beispiel):
- Auth (Session-Token) anfordern — Beispiel (ersetze Platzhalter):
curl -s -X POST "%METABASE_URL%/api/session" -H "Content-Type: application/json" -d "{\"username\": \"%METABASE_USER%\", \"password\": \"%METABASE_PASSWORD%\"}"
- Export anfragen (Beispiel: PDF-Export eines Cards/Dashboards). Je nach Metabase-Version kann der Pfad variieren. Beispiel-Form (Platzhalter):
curl -s -X POST "%METABASE_URL%/api/card/%METABASE_CARD_ID%/query/pdf" -H "Content-Type: application/json" -H "X-Metabase-Session: <SESSION_TOKEN>" --output metabase-report.pdf
Validierung:
- Datei
metabase-report.pdfexistiert und ist > 50 KB. - Öffne die Datei lokal im PDF-Viewer und prüfe, ob Daten sichtbar sind.
Troubleshooting:
- Auth schlägt fehl → Credentials prüfen, ggf. IP-Restrictions.
- Endpoint nicht vorhanden → Metabase-Dokumentation zur API-Version prüfen (Session-API / Export-Endpoints variieren).
- Teamup — lokaler API-Test
Zweck: Kalenderdaten per API abrufen oder Wochenansicht via Headless-Browser rendern.
Vorgehen:
- Env-Variablen:
TEAMUP_CALENDAR_BASE=https://api.teamup.comTEAMUP_CALENDAR_KEY=dein_calendar_key(oderTEAMUP_PUBLIC_URLfür Web-Rendering)- Optional:
TEAMUP_API_KEY=...falls benötigt
API-Request (Events im Zeitraum abrufen) — Beispiel:
curl -s -H "Teamup-Token: %TEAMUP_API_KEY%" "%TEAMUP_CALENDAR_BASE%/v2/calendars/%TEAMUP_CALENDAR_KEY%/events?startDate=2025-11-01&endDate=2025-11-14" | jq '.'
Alternativ (wenn du die Web-Ansicht als Bild willst):
- Öffne die Wochen-URL (z. B.
%TEAMUP_PUBLIC_URL%?view=week&date=YYYY-MM-DD) mit einem Headless-Renderer (Puppeteer) und erstelleteamup-week1.png.
Validierung:
- API: JSON-Antwort mit Events (Array) und HTTP 200.
- Screenshot:
teamup-week1.pngist vorhanden und lesbar.
Troubleshooting:
- 403/401 → API-Key oder Zugriff prüfen.
- Keine Events → Zeitraum / Kalenderkey kontrollieren.
- DokuWiki — lokaler API-Test (empfohlen: API) oder SSH-Fallback
Zweck: Eine Testseite erzeugen und Medien verlinken, um Upload & Sichtbarkeit zu prüfen.
Vorgehen (API-Variante, wenn DOKUWIKI_API_URL + DOKUWIKI_API_TOKEN vorhanden):
- Env-Variablen:
DOKUWIKI_API_URL=https://wiki.example.com/lib/exe/rest.php/bin/actions(Beispiel – passe an)DOKUWIKI_API_TOKEN=...WIKI_MEETING_NAMESPACE=teammeetingsMEETING_ID=2025-11
Beispiel (allgemeines curl-Pattern; Plugin/Endpoint anpassen):
set /p PAGE_TEXT=< newpage.txt
curl -s -X POST "%DOKUWIKI_API_URL%" -H "Authorization: Bearer %DOKUWIKI_API_TOKEN%" -F "id=%WIKI_MEETING_NAMESPACE%:%MEETING_ID%" -F "text=%PAGE_TEXT%"
Wenn keine API verfügbar ist (SSH-Fallback):
- Upload der Medien per
scpoderrsync -e sshin${ALLINKL_BASE_PATH}/data/media/...und Schreiben der Seite per SSH-Here-Doc (wie im Plan beschrieben).
Validierung:
- Nach API-Request: die Seite im Browser öffnen (z. B.
https://wiki.example.com/doku.php?do=show&id=%WIKI_MEETING_NAMESPACE%:%MEETING_ID%) → HTTP 200 und sichtbarer Inhalt. - Medien sind im Wiki sichtbar und korrekt verlinkt.
Troubleshooting:
- API 401/403 → Token prüfen / Plugin aktivieren.
- SSH-Fallback: Dateirechte und Ownership prüfen (All-Inkl kann hier beschränken).
.env.example— minimale Variablen (Beispiel zum Anlegen)
# Metabase
METABASE_URL=
METABASE_USER=
METABASE_PASSWORD=
METABASE_CARD_ID=
# Teamup
TEAMUP_CALENDAR_BASE=
TEAMUP_CALENDAR_KEY=
TEAMUP_API_KEY=
# DokuWiki (API bevorzugt)
DOKUWIKI_API_URL=
DOKUWIKI_API_TOKEN=
WIKI_MEETING_NAMESPACE=teammeetings
# Fallback/SSH (nur falls nötig)
ALLINKL_SSH_HOST=
ALLINKL_SSH_USER=
ALLINKL_BASE_PATH=
# TZ
TZ=Europe/Berlin
- Ablauf für lokale Durchführung (kurz)
.envaus.env.exampleanlegen und mit echten (lokal gültigen) Werten füllen.- Prüfe Tools:
curl --version,node --version(falls Renderer benötigt),jq --version. - Metabase-Test ausführen (Auth → Export → Datei prüfen).
- Teamup-Test ausführen (API → JSON prüfen oder Screenshot erzeugen).
- DokuWiki-Test ausführen (API → Seite prüfen). Falls API nicht vorhanden, teste SSH-Fallback.
- Wenn alle drei Tests grün sind, kannst du
monthly_export.shlokal im Dry-Run-Mode ausführen und anschließend per Gitea-Action in den Runner überführen.
- Minimal gewünschte Ergebnisse (zum Abhaken)
- Metabase PDF lokal erzeugt und geprüft
- Teamup-Daten/API oder Screenshots erzeugt und geprüft
- DokuWiki-Seite erstellt/aktualisiert und Medien referenziert
Wenn du möchtest, erstelle ich als nächstes eine .env.example-Datei im Repo und ein sehr kleines Shell-Skript-Skeleton (./scripts/test_apis.sh) mit den obenstehenden curl-Beispielen (ohne Secrets). Sag kurz Bescheid, ob ich das anlegen soll.