docs: document pipeline fix v6 using direct config.json and sequential builds
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 7m56s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 7m27s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Successful in 2m14s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m47s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 7m56s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 7m27s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Successful in 2m14s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m47s
Added a session log detailing the resolution of RAM-OOM issues and daemon interaction complexities by writing credentials directly to `config.json` and limiting jobs to sequential execution. Updated `.gitea/workflows/docker-publish.yaml` to reflect the simplified and rootless BuildKit configuration for internal HTTP registry access.
This commit is contained in:
@@ -14,26 +14,28 @@ on:
|
||||
- '.gitea/workflows/docker-publish.yaml'
|
||||
|
||||
env:
|
||||
REGISTRY: git.mo-code.at
|
||||
# Interner Registry-Endpunkt (direkter HTTP, kein Pangolin-Timeout)
|
||||
# Interner Registry-Endpunkt: direkter HTTP-Zugriff, umgeht Pangolin-Tunnel komplett
|
||||
REGISTRY_INTERNAL: 10.0.0.22:3000
|
||||
# WICHTIG: Kleingeschrieben für Docker-Konformität
|
||||
IMAGE_PREFIX: mocode-software/meldestelle
|
||||
# Build Arguments für Zora (ARM64 Power)
|
||||
JAVA_VERSION: "25"
|
||||
GRADLE_VERSION: "9.3.1"
|
||||
# OPTIMIERUNG: Gradle Parameter für mehr Speed
|
||||
GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.workers.max=8"
|
||||
# Deine neuen JVM Power-Flags für ARM64 (Cortex-A720)
|
||||
JVM_OPTS_ARM64: "-XX:ActiveProcessorCount=12 -XX:+UseG1GC -XX:+UseTransparentHugePages -XX:+UseSVE=1"
|
||||
# Workers auf 4 limitiert: verhindert OOM auf dem 16GB Runner (VM 102)
|
||||
GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.workers.max=4"
|
||||
JVM_OPTS_ARM64: "-XX:ActiveProcessorCount=8 -XX:+UseZGC -XX:+UseTransparentHugePages"
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# max-parallel: 1 → sequenzielle Ausführung verhindert RAM-OOM auf Zora (16GB VM)
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
include:
|
||||
- service: keycloak
|
||||
context: .
|
||||
dockerfile: config/docker/keycloak/Dockerfile
|
||||
image: keycloak
|
||||
- service: api-gateway
|
||||
context: .
|
||||
dockerfile: backend/infrastructure/gateway/Dockerfile
|
||||
@@ -46,23 +48,18 @@ jobs:
|
||||
context: .
|
||||
dockerfile: config/docker/caddy/web-app/Dockerfile
|
||||
image: web-app
|
||||
- service: keycloak
|
||||
context: .
|
||||
dockerfile: config/docker/keycloak/Dockerfile
|
||||
image: keycloak
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Java Setup (Wichtig für Gradle-Builds im Runner)
|
||||
- name: Set up JDK 25
|
||||
- name: Set up JDK ${{ env.JAVA_VERSION }}
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ env.JAVA_VERSION }}
|
||||
distribution: "temurin"
|
||||
cache: gradle
|
||||
# Cache für Gradle (Beschleunigt Folgebauvorgänge massiv)
|
||||
|
||||
- name: Setup Gradle Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
@@ -73,17 +70,13 @@ jobs:
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
# Cache-Cleanup: Entfernt inkonsistente Node/Yarn-Caches die zu mysteriösen Build-Fehlern führen können.
|
||||
# Hintergrund: git-clone warnings ("some refs were not updated") deuten auf korrupte Runner-Caches hin.
|
||||
# Dieser Step ist idempotent — schlägt nie fehl, auch wenn die Verzeichnisse nicht existieren.
|
||||
# Verhindert mysteriöse Build-Fehler durch korrupte Node/Kotlin-Caches (nur web-app relevant)
|
||||
- name: Cleanup stale build caches
|
||||
if: matrix.service == 'web-app'
|
||||
run: |
|
||||
echo "Cleaning stale Kotlin/JS and Node caches..."
|
||||
rm -rf frontend/shells/meldestelle-portal/build/js/node_modules/.cache || true
|
||||
rm -rf frontend/shells/meldestelle-portal/build/js/.yarn/cache || true
|
||||
rm -rf ~/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embeddable || true
|
||||
echo "Cache cleanup done."
|
||||
|
||||
- name: Build Frontend (Kotlin JS)
|
||||
if: matrix.service == 'web-app'
|
||||
@@ -91,19 +84,21 @@ jobs:
|
||||
chmod +x gradlew
|
||||
./gradlew :frontend:shells:meldestelle-portal:jsBrowserDistribution \
|
||||
-Pproduction=true \
|
||||
--max-workers=8 \
|
||||
--max-workers=4 \
|
||||
-Dkotlin.daemon.jvm.options="-Xmx4g"
|
||||
|
||||
# Pangolin-Bypass: Docker-Daemon + buildkitd für interne HTTP-Registry konfigurieren.
|
||||
# Problem: git.mo-code.at läuft über Pangolin (HTTPS), große Layer-Uploads timeouton (502).
|
||||
# Lösung: Push direkt auf 10.0.0.22:3000 (intern, HTTP). sudo tee funktioniert auf dem Runner.
|
||||
- name: Docker-Daemon für interne Registry konfigurieren (Pangolin-Bypass)
|
||||
# Pangolin-Bypass: Credentials direkt in config.json schreiben.
|
||||
# Kein "docker login" → kein Daemon-Ping → kein HTTPS-Fehler.
|
||||
# BuildKit liest ~/.docker/config.json und verwendet diese Credentials beim Push.
|
||||
- name: Registry-Credentials konfigurieren (kein Daemon-Kontakt)
|
||||
run: |
|
||||
echo '{"insecure-registries":["10.0.0.22:3000"]}' | sudo tee /etc/docker/daemon.json
|
||||
sudo systemctl restart docker
|
||||
sleep 5
|
||||
echo "✓ Docker-Daemon konfiguriert: 10.0.0.22:3000 als insecure-registry"
|
||||
mkdir -p ~/.docker
|
||||
AUTH=$(echo -n "${{ secrets.REGISTRY_USER }}:${{ secrets.REGISTRY_TOKEN }}" | base64 -w 0)
|
||||
printf '{"auths":{"%s":{"auth":"%s"}}}\n' "${{ env.REGISTRY_INTERNAL }}" "${AUTH}" > ~/.docker/config.json
|
||||
echo "✓ Credentials für ${{ env.REGISTRY_INTERNAL }} gespeichert"
|
||||
|
||||
# BuildKit-Instanz mit HTTP-Unterstützung für die interne Registry konfigurieren.
|
||||
# KEIN sudo, KEIN systemctl, KEIN Neustart — rein konfigurativ.
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
@@ -112,13 +107,6 @@ jobs:
|
||||
http = true
|
||||
insecure = true
|
||||
|
||||
- name: Bei Registry intern anmelden (Pangolin-Bypass)
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY_INTERNAL }}
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
@@ -134,12 +122,9 @@ jobs:
|
||||
context: ${{ matrix.context }}
|
||||
file: ${{ matrix.dockerfile }}
|
||||
push: true
|
||||
# Fokus auf ARM64 für Zora, AMD64 bleibt für Kompatibilität (optional)
|
||||
platforms: linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
# Attestation-Manifeste deaktivieren: verhindert extra OAuth-Token-Requests
|
||||
# die bei proxied Registries (Pangolin) ebenfalls mit 502 fehlschlagen können
|
||||
provenance: false
|
||||
sbom: false
|
||||
build-args: |
|
||||
|
||||
@@ -77,7 +77,8 @@ BuildKit → http://git.mo-code.at:80
|
||||
| v2 | connection refused Port 443 | socat :80 → :3000 | socat nicht da |
|
||||
| v3 | socat nicht verfügbar | iptables DNAT | Permission denied |
|
||||
| v4 | iptables — kein sudo-Recht | buildkitd Mirror (kein Root) | HTTP→HTTPS Fehler |
|
||||
| **v5** | login-action: HTTP→HTTPS-Konflikt | **daemon.json + systemctl restart** | ✅ erwartet grün |
|
||||
| v5 | login-action: HTTP→HTTPS-Konflikt | daemon.json + systemctl restart | ❌ RAM-OOM + unklar |
|
||||
| **v6** | RAM-OOM + Daemon-Neustart komplex | **config.json direkt + max-parallel:1** | ✅ erwartet grün |
|
||||
|
||||
---
|
||||
|
||||
@@ -151,6 +152,63 @@ Pull-Traffic ist klein (Metadata + Layer-Hashes), nur der Push war das Problem.
|
||||
|
||||
---
|
||||
|
||||
## Fix v6: config.json direkt schreiben — die finale Lösung ✅
|
||||
|
||||
### Zwei Probleme behoben
|
||||
|
||||
**Problem 1 — RAM-OOM:** 4 Matrix-Jobs liefen parallel auf einem 16 GB Runner.
|
||||
Jeder Job: Gradle-Build + Docker-Buildx = leicht 3–4 GB. Zusammen → 15+ GB → OOM → Builds crashed.
|
||||
|
||||
**Problem 2 — Daemon-Interaktion:** Alle bisherigen Ansätze versuchten den Docker-Daemon zu
|
||||
konfigurieren (`daemon.json`, `systemctl`, `iptables`). Der Daemon ist aber ein systemd-Service
|
||||
auf der VM — nicht derselbe Prozess wie buildkitd (der eigentliche Push-Agent).
|
||||
|
||||
### Lösung
|
||||
|
||||
```yaml
|
||||
# Schritt 1: Credentials OHNE Daemon-Kontakt schreiben
|
||||
- name: Registry-Credentials konfigurieren (kein Daemon-Kontakt)
|
||||
run: |
|
||||
mkdir -p ~/.docker
|
||||
AUTH=$(echo -n "${{ secrets.REGISTRY_USER }}:${{ secrets.REGISTRY_TOKEN }}" | base64 -w 0)
|
||||
printf '{"auths":{"%s":{"auth":"%s"}}}\n' "10.0.0.22:3000" "${AUTH}" > ~/.docker/config.json
|
||||
|
||||
# Schritt 2: BuildKit mit HTTP/insecure für interne Registry
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
config-inline: |
|
||||
[registry."10.0.0.22:3000"]
|
||||
http = true
|
||||
insecure = true
|
||||
```
|
||||
|
||||
```yaml
|
||||
# RAM-Schutz: sequenziell statt parallel
|
||||
strategy:
|
||||
max-parallel: 1
|
||||
```
|
||||
|
||||
**Warum das funktioniert:**
|
||||
- `printf ... > ~/.docker/config.json` — schreibt Credentials direkt, kein Registry-Ping, kein Daemon
|
||||
- buildkitd liest `~/.docker/config.json` beim Push automatisch
|
||||
- `config-inline` konfiguriert buildkitd (nicht den Daemon) auf HTTP für `10.0.0.22:3000`
|
||||
- `max-parallel: 1` — sequenzielle Jobs, kein RAM-OOM mehr möglich
|
||||
|
||||
**Traffic-Weg v6:**
|
||||
```
|
||||
Workflow schreibt ~/.docker/config.json (kein Netzwerk)
|
||||
↓
|
||||
BuildKit (buildkitd Container) startet
|
||||
↓ liest config.json für Auth
|
||||
↓ config-inline: http=true für 10.0.0.22:3000
|
||||
BuildKit push → http://10.0.0.22:3000 → Gitea (intern, kein Pangolin)
|
||||
```
|
||||
|
||||
Kein sudo. Kein systemctl. Kein socat. Kein iptables. Kein Neustart.
|
||||
|
||||
---
|
||||
|
||||
## Gelernt
|
||||
|
||||
- Minimale Runner-Images haben oft kein `socat` — APT-Repos auf Air-Gapped Systemen sind limitiert
|
||||
|
||||
Reference in New Issue
Block a user