--- type: Journal status: ACTIVE owner: Lead Architect date: 2026-03-06 last_update: 2026-03-06 --- # Session Log — Pipeline vollständig grün ✅ **Datum:** 06.03.2026 **Agent:** 🏗️ Lead Architect **Thema:** CI/CD Pipeline — alle 4 Jobs erfolgreich bestätigt --- ## Ergebnis Alle vier Build-and-Push-Jobs sind grün: | Job | Status | |-----|--------| | `api-gateway` (backend/infrastructure/gateway/Dockerfile) | ✅ grün | | `ping-service` (backend/services/ping/Dockerfile) | ✅ grün | | `web-app` (config/docker/caddy/web-app/Dockerfile) | ✅ grün | | `keycloak` (config/docker/keycloak/Dockerfile) | ✅ grün | --- ## Root Causes (Gesamtüberblick) Die Pipeline hatte **zwei voneinander unabhängige Probleme**, die zusammen alle Pushes verhinderten: ### Problem 1: Pangolin-Tunnel als Registry-Proxy (Hauptursache) Der Gitea-Runner (VM 102, `10.0.0.23`) kannte `git.mo-code.at` nur über den Pangolin-Tunnel (öffentliche DNS-Auflösung → Pangolin → HTTPS → Gitea). Bei großen Image-Layern (70+ Sekunden Upload) timeoutet Pangolin → `502 Bad Gateway`. **Lösung (v6):** Credentials direkt in `~/.docker/config.json` schreiben (kein Daemon-Ping), buildkitd via `config-inline` auf `http://10.0.0.22:3000` zeigen (intern, kein Pangolin). ### Problem 2: RAM-OOM auf 16 GB Runner 4 Matrix-Jobs liefen parallel. Jeder Job: Gradle-Build + Docker-Buildx = 3–4 GB RAM. Zusammen: 15+ GB → RAM-Erschöpfung → Builds crashed/hingen. **Lösung (v6):** `max-parallel: 1` — Jobs laufen sequenziell, Runner bleibt stabil. --- ## Finale Lösung (v6) — die funktionierenden Kern-Änderungen ```yaml strategy: max-parallel: 1 # ← RAM-Schutz: kein OOM mehr steps: - name: Registry-Credentials konfigurieren (kein Daemon-Kontakt) run: | mkdir -p ~/.docker printf '{"auths":{"10.0.0.22:3000":{"auth":"%s"}}}' \ "$(printf '%s:%s' '${{ secrets.REGISTRY_USER }}' '${{ secrets.REGISTRY_TOKEN }}' | base64 -w0)" \ > ~/.docker/config.json - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: config-inline: | [registry."git.mo-code.at"] mirrors = ["http://10.0.0.22:3000"] http = true insecure = true [registry."10.0.0.22:3000"] http = true insecure = true ``` **Traffic-Weg (intern, kein Pangolin):** ``` BuildKit → push git.mo-code.at/mocode-software/meldestelle/:latest → buildkitd config-inline Mirror: http://10.0.0.22:3000 → Gitea Registry (HTTP, direkt intern) → ✅ kein Pangolin, kein Timeout, kein TLS-Konflikt ``` --- ## Warum 6 Iterationen nötig waren | Version | Blockiert durch | |---------|----------------| | v1 | Pangolin 502 beim Push großer Layer | | v2 | `socat` nicht im APT-Repo des Runners | | v3 | `iptables` benötigt Root — Runner-User hat kein sudo für iptables | | v4 | buildkitd-Mirror funktioniert für Pulls, nicht für Pushes von `login-action` | | v5 | `systemctl restart docker` benötigt Root + RAM-OOM durch parallele Jobs | | **v6** | **Beide Root Causes gleichzeitig behoben → ✅ grün** | --- ## Gelernt - **Pangolin ist kein Registry-Proxy** — ausschließlich Pull-Traffic (klein) läuft über Pangolin. Push-Traffic (groß, langsam) muss intern bleiben. - **buildkitd ≠ Docker-Daemon** — beide Prozesse müssen separat konfiguriert werden. `login-action` → Daemon; `build-push-action` → buildkitd. - **`~/.docker/config.json` direkt schreiben** umgeht den Daemon vollständig — kein Ping, kein HTTPS-Test. - **`max-parallel: 1`** ist auf einem 16 GB Runner mit Gradle + Buildx Pflicht. - Permanente Lösung für die Zukunft: `insecure-registries` einmalig in `/etc/docker/daemon.json` auf VM 102 setzen → `login-action` kann wieder normal verwendet werden. --- ## Nächste Schritte 1. **Permanent (einmalig auf VM 102):** `/etc/docker/daemon.json` → `insecure-registries: ["10.0.0.22:3000"]` → dann kann der `config.json`-Workaround durch `docker/login-action` ersetzt werden. 2. **Meldestelle-Host:** `.env` mit Server-IP befüllen, Container neu starten, Ping-Service testen. 3. **Grafana + Pangolin-URLs** konfigurieren (nächste Session). 4. **Ollama + Open WebUI** auf Proxmox LXC einrichten (übernächste Session).