Local Build Pipeline #139

Open
opened 2026-07-24 19:33:32 +02:00 by thomasknaus · 1 comment
thomasknaus commented 2026-07-24 19:33:32 +02:00 (Migrated from github.com)

Der Intel Mac Mini ist eine hervorragende Hardware-Basis für dieses Vorhaben. Forgejo selbst ist extrem genügsam, die eigentliche Last entsteht durch die CI/CD-Prozesse.

Technische Voraussetzungen (Mac Mini Intel)

Für den reinen Betrieb des Code-Repositories und der Registry reicht fast jeder Computer. Die Spezifikationen des Mac Mini müssen jedoch den CI/CD-Workflows standhalten:

  • Prozessor (CPU): Die Intel Core i3, i5 oder i7 Prozessoren (4 bis 6 Kerne) sind völlig ausreichend. Forgejo benötigt im Leerlauf nur einen Bruchteil eines Kerns.
  • Arbeitsspeicher (RAM): Da parallele Build-Pipelines für jeden Job eigene, isolierte Docker-Container hochfahren, wird der RAM schnell zum Flaschenhals. Die 8 GB Basisversion des Mac Mini reicht für das System und 1-2 gleichzeitige, kleine Jobs. Für mehrere parallele Builds solltest du den Mac Mini auf 16 GB oder 32 GB aufrüsten (was bei der Intel-Version über Standard-SO-DIMMs problemlos möglich ist).
  • Speicher (SSD): CI/CD-Pipelines erzeugen viele Lese-/Schreibzugriffe (Docker-Layer laden, Repositories auschecken). Die fest verbauten PCIe-SSDs im Mac Mini sind dafür optimal und beschleunigen die Build-Zeiten massiv.

Forgejo & CI/CD Runner aufsetzen

Diese Anleitung nutzt Docker Compose, um sowohl den Forgejo-Server als auch den zugehörigen Runner (für die Actions) auf dem Mac Mini bereitzustellen. Voraussetzung ist, dass [Docker Desktop für Mac](https://docs.docker.com/desktop/install/mac-install/) installiert ist.

  1. Projektverzeichnis anlegen:
    Öffne das Terminal auf dem Mac Mini und erstelle einen Ordner für die Konfiguration und die persistenten Daten:
mkdir -p ~/forgejo-setup
cd ~/forgejo-setup

  1. docker-compose.yml erstellen:
    Erstelle im neuen Verzeichnis eine Datei namens docker-compose.yml mit folgendem Inhalt. Diese Datei definiert den Server und den Runner, der später den Zugriff auf den Docker-Socket erhält, um Container für die Build-Jobs zu starten.
services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:8
    container_name: forgejo
    ports:
      - "3000:3000"
      - "2222:22"
    volumes:
      - ./forgejo-data:/data
    restart: always

  runner:
    image: code.forgejo.org/forgejo/runner:3
    container_name: forgejo-runner
    volumes:
      - ./runner-data:/data
      - /var/run/docker.sock:/var/run/docker.sock
    restart: always

  1. Forgejo starten und einrichten:
    Starte zunächst nur den Forgejo-Server:
docker compose up -d forgejo

Rufe nun im Browser http://localhost:3000 auf. Schließe die Initialeinrichtung ab (die Standardeinstellung mit SQLite-Datenbank reicht für lokale Setups völlig aus). Erstelle dabei dein Administrator-Konto.

  1. Runner-Token generieren:
    Damit der Runner Aufträge entgegennehmen darf, benötigt er eine Berechtigung:

  2. Gehe in Forgejo oben rechts auf Website-Administration.

  3. Wähle im linken Menü Aktionen -> Runner.

  4. Klicke auf Neuen Runner erstellen und kopiere den angezeigten Registrierungs-Token.

  5. Runner registrieren und starten:
    Lass nun den Runner-Container starten und registriere ihn mit einem Einzeiler im Terminal. Ersetze <DEIN_TOKEN> durch den kopierten Wert.

# Runner-Container starten
docker compose up -d runner

# Runner an Forgejo binden
docker exec -it forgejo-runner forgejo-runner register \
  --no-interactive \
  --token <DEIN_TOKEN> \
  --name "Mac-Mini-Runner" \
  --instance http://forgejo:3000

Sobald der Runner registriert ist, taucht er im Admin-Panel von Forgejo mit dem Status "Online" auf. Ab jetzt kannst du im .forgejo/workflows Verzeichnis deiner Code-Repositories YAML-Dateien ablegen, die genauso funktionieren wie bei GitHub Actions.

Der Intel Mac Mini ist eine hervorragende Hardware-Basis für dieses Vorhaben. Forgejo selbst ist extrem genügsam, die eigentliche Last entsteht durch die CI/CD-Prozesse. ## Technische Voraussetzungen (Mac Mini Intel) Für den reinen Betrieb des Code-Repositories und der Registry reicht fast jeder Computer. Die Spezifikationen des Mac Mini müssen jedoch den CI/CD-Workflows standhalten: * **Prozessor (CPU):** Die Intel Core i3, i5 oder i7 Prozessoren (4 bis 6 Kerne) sind völlig ausreichend. Forgejo benötigt im Leerlauf nur einen Bruchteil eines Kerns. * **Arbeitsspeicher (RAM):** Da parallele Build-Pipelines für jeden Job eigene, isolierte Docker-Container hochfahren, wird der RAM schnell zum Flaschenhals. Die 8 GB Basisversion des Mac Mini reicht für das System und 1-2 gleichzeitige, kleine Jobs. Für mehrere parallele Builds solltest du den Mac Mini auf 16 GB oder 32 GB aufrüsten (was bei der Intel-Version über Standard-SO-DIMMs problemlos möglich ist). * **Speicher (SSD):** CI/CD-Pipelines erzeugen viele Lese-/Schreibzugriffe (Docker-Layer laden, Repositories auschecken). Die fest verbauten PCIe-SSDs im Mac Mini sind dafür optimal und beschleunigen die Build-Zeiten massiv. --- ## Forgejo & CI/CD Runner aufsetzen Diese Anleitung nutzt Docker Compose, um sowohl den Forgejo-Server als auch den zugehörigen Runner (für die Actions) auf dem Mac Mini bereitzustellen. Voraussetzung ist, dass [[Docker Desktop für Mac](https://docs.docker.com/desktop/install/mac-install/)](https://docs.docker.com/desktop/install/mac-install/) installiert ist. 1. **Projektverzeichnis anlegen:** Öffne das Terminal auf dem Mac Mini und erstelle einen Ordner für die Konfiguration und die persistenten Daten: ```bash mkdir -p ~/forgejo-setup cd ~/forgejo-setup ``` 2. **docker-compose.yml erstellen:** Erstelle im neuen Verzeichnis eine Datei namens `docker-compose.yml` mit folgendem Inhalt. Diese Datei definiert den Server und den Runner, der später den Zugriff auf den Docker-Socket erhält, um Container für die Build-Jobs zu starten. ```yaml services: forgejo: image: codeberg.org/forgejo/forgejo:8 container_name: forgejo ports: - "3000:3000" - "2222:22" volumes: - ./forgejo-data:/data restart: always runner: image: code.forgejo.org/forgejo/runner:3 container_name: forgejo-runner volumes: - ./runner-data:/data - /var/run/docker.sock:/var/run/docker.sock restart: always ``` 3. **Forgejo starten und einrichten:** Starte zunächst nur den Forgejo-Server: ```bash docker compose up -d forgejo ``` Rufe nun im Browser `http://localhost:3000` auf. Schließe die Initialeinrichtung ab (die Standardeinstellung mit SQLite-Datenbank reicht für lokale Setups völlig aus). Erstelle dabei dein Administrator-Konto. 4. **Runner-Token generieren:** Damit der Runner Aufträge entgegennehmen darf, benötigt er eine Berechtigung: 1. Gehe in Forgejo oben rechts auf **Website-Administration**. 2. Wähle im linken Menü **Aktionen** -> **Runner**. 3. Klicke auf **Neuen Runner erstellen** und kopiere den angezeigten **Registrierungs-Token**. 5. **Runner registrieren und starten:** Lass nun den Runner-Container starten und registriere ihn mit einem Einzeiler im Terminal. Ersetze `<DEIN_TOKEN>` durch den kopierten Wert. ```bash # Runner-Container starten docker compose up -d runner # Runner an Forgejo binden docker exec -it forgejo-runner forgejo-runner register \ --no-interactive \ --token <DEIN_TOKEN> \ --name "Mac-Mini-Runner" \ --instance http://forgejo:3000 ``` Sobald der Runner registriert ist, taucht er im Admin-Panel von Forgejo mit dem Status "Online" auf. Ab jetzt kannst du im `.forgejo/workflows` Verzeichnis deiner Code-Repositories YAML-Dateien ablegen, die genauso funktionieren wie bei GitHub Actions.
thomasknaus commented 2026-07-24 19:53:11 +02:00 (Migrated from github.com)

Migration von GitHub zu Forgejo (Self-Hosted) — Machbarkeitsanalyse

Repository: AISimulate-Engineering/RaceEngineer (Pitwall Pro)

Commit: 52b28f4 · Stand: 07/2026


1. Architektur & Abhängigkeiten (Codebasis)

1.1 Technologie-Stack

Komponente Sprache Framework / Runtime Build-Output
Backend Rust (Edition 2021) Actix-Web (HTTP), SQLx (DB), tokio (async) Native Binary (Linux x86_64)
Desktop-App Rust + Dioxus Tauri (GUI), ONNX Runtime (ML), whisper-rs (Speech) Native Binary (Win/macOS)
HUD-Sidecar Rust + Tauri Eigenständiges Fenster für Overlay Native Binary
Admin-Desktop Rust + Dioxus Desktop-Admin-Panel Native Binary
Web-App Rust + Dioxus WASM (wasm32-unknown-unknown), Tailwind CSS WASM + HTML/JS/CSS
Frontend (shared) Rust Dioxus Komponenten-Bibliothek Library Crate
Core (shared) Rust Domain-Logik, Shared Types Library Crate
Common-Client Rust Gemeinsame Client-Logik Library Crate
Altes JVM-Backend Kotlin/JVM Gradle, Ktor Fat JAR (obsolet)

Rust-Edition: 2021 · Build-System: Cargo Workspace mit 7 Member-Crates + 1 excluded (pitwall-hud)

1.2 Abhängigkeitsmanagement

  • Rust: Cargo.toml / Cargo.lock (alle Crates außer pitwall-hud sind Workspace-Members)
  • Node.js: web-app/package.json (Tailwind CSS), package.json im Root
  • Python: Flask (Mock-Server für E2E-Tests), huggingface_hub (Modell-Downloads)
  • Gradle: Nur für das obsolete JVM-Backend

1.3 Datenbanken & Services

Service Zweck Status
PostgreSQL 16 Primäre Datenbank (Benutzer, Lizenzen, Sessions, Billing, Telemetrie) Kritisch
MinIO / S3-kompatibel Telemetrie-Uploads, Track-Baselines, Backups (WAL-G) Kritisch für Produktion
Redis 7 Caching/Sessions (im Test-Compose definiert) Optional
Traefik v2.10 Reverse-Proxy mit automatischem Let's Encrypt TLS Produktion
Ofelia Cron-in-Docker für DB-Backups (pg_dump + wal-g) Produktion
Lemon Squeezy / PayPal Externe Zahlungsdienstleister (Billing) Extern (SaaS)
Discord / Google / Microsoft / Steam OAuth Social Login Extern (SaaS)
Sentry Error-Tracking (optional) Extern (SaaS)
Prometheus + Grafana Monitoring (separate Compose-Files vorhanden) Optional

Datenbank-Migrationen: 11 Migrationspaare, verwaltet mit sqlx-cli. Kern-Tabellen: licenses, users, app_errors, track_baselines, billing_plans, discount_codes, system_options, sessions, telemetry_history.

1.4 Dateisystem-Interaktionen

  • Config-Verzeichnis: backend-rs/config/ wird relativ zum Binary-Arbeitsverzeichnis aufgelöst — Docker-kompatibel.
  • Modelle für ML: desktop-app/assets/models/ (ONNX Runtime, Qwen LLM, Kokoro TTS). Zur Build-Zeit eingebettet.
  • Persistente Daten: Alle als Docker-Volumes gemountet — keine harten Pfadabhängigkeiten.
  • Secrets: Docker Secrets (/run/secrets/<name>) für Produktion, .env für Entwicklung.
  • Keine kritischen Hardcoded-Pfade gefunden.

2. Containerisierung (Docker-Bereitschaft)

2.1 Dockerfile-Analyse

Datei Bewertung
backend-rs/Dockerfile Hervorragend — 3-Stage-Build, Distroless-Runtime, Non-Root
Root Dockerfile ⚠️ Obsolet — Kotlin/JVM
Dockerfile.test ⚠️ Obsolet — JVM-Test-Runner
backend-rs/Dockerfile.db Custom PostgreSQL mit wal-g für PITR-Backups

backend-rs/Dockerfile — detaillierte Bewertung:

Stage 1 (builder):  rust:bookworm           → Kompiliert das Rust-Binary
Stage 2 (deps):     debian:bookworm-slim    → Extrahiert libasound2
Stage 3 (runtime):  gcr.io/distroless/cc-debian12:nonroot → Minimal, kein Root

Stärken:

  • Multi-Stage Build minimiert Image-Größe
  • Distroless-Runtime (kein Shell, kein Package-Manager)
  • Non-Root-User (UID 65532) standardmäßig
  • Build-Args: CARGO_JOBS, BUILD_MODE für flexible Builds
  • --locked für reproduzierbare Builds
  • CARGO_INCREMENTAL=0, LTO=false, codegen-units=16 für CI-optimiertes Bauen

2.2 12-Factor-App Konformität

Factor Status
I. Codebase Ein Monorepo, ein Codebase
II. Dependencies Cargo.lock + package-lock.json
III. Config Env-Vars + Docker Secrets
IV. Backing Services DB/S3 als konfigurierbare Resources
V. Build/Release/Run Multi-Stage Dockerfile
VI. Processes Stateless Binary
VII. Port Binding BACKEND_ADDR=0.0.0.0:3000
VIII. Concurrency Actix-Web async
IX. Disposability Graceful Shutdown via Actix
X. Dev/Prod Parity Docker Compose für beide Umgebungen
XI. Logs stdout-Logging via RUST_LOG / RUST_LOG_JSON
XII. Admin Processes sqlx migrate run als One-Off-Prozess

Fazit: Sehr hohe 12-Factor-Konformität. Keine strukturellen Änderungen nötig.

2.3 Optimiertes Dockerfile mit cargo-chef

# ─── Stage 0: Cargo Chef (Dependency-Caching) ─────────────────────────────
FROM rust:bookworm AS chef
RUN cargo install cargo-chef --locked
WORKDIR /usr/src/app

# ─── Stage 1: Plan (nur Cargo.toml/Cargo.lock für Dependency-Layer) ───────
FROM chef AS planner
COPY Cargo.toml Cargo.lock ./
COPY core/Cargo.toml core/
COPY common-client/Cargo.toml common-client/
COPY frontend/Cargo.toml frontend/
COPY backend-rs/Cargo.toml backend-rs/
COPY backend-rs/config backend-rs/config/
RUN mkdir -p core/src common-client/src frontend/src backend-rs/src && \
    echo "pub fn dummy() {}" > core/src/lib.rs && \
    echo "pub fn dummy() {}" > common-client/src/lib.rs && \
    echo "pub fn dummy() {}" > frontend/src/lib.rs && \
    echo "fn main() {}" > backend-rs/src/main.rs
RUN cargo chef prepare --recipe-path recipe.json

# ─── Stage 2: Build Dependencies (cached) ─────────────────────────────────
FROM chef AS builder
RUN apt-get update && apt-get install -y --no-install-recommends libasound2-dev && \
    rm -rf /var/lib/apt/lists/*
COPY --from=planner /usr/src/app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
COPY . .
ARG CARGO_JOBS=1
ARG BUILD_MODE=release
ENV CARGO_INCREMENTAL=0
RUN if [ "$BUILD_MODE" = "release" ]; then \
      cargo build --release --locked --package pitwall-pro-backend-rs --jobs $CARGO_JOBS; \
    else \
      cargo build --locked --package pitwall-pro-backend-rs --jobs $CARGO_JOBS; \
    fi && \
    mkdir -p /app-bin && \
    if [ "$BUILD_MODE" = "release" ]; then \
      cp target/release/pitwall-pro-backend-rs /app-bin/; \
    else \
      cp target/debug/pitwall-pro-backend-rs /app-bin/; \
    fi

# ─── Stage 3: Runtime ─────────────────────────────────────────────────────
FROM gcr.io/distroless/cc-debian12:nonroot AS runtime
COPY --from=builder /app-bin/pitwall-pro-backend-rs /app/pitwall-pro-backend-rs
COPY --from=builder /usr/src/app/backend-rs/config /app/config
WORKDIR /app
EXPOSE 3000
CMD ["/app/pitwall-pro-backend-rs"]

2.4 Docker Compose für Self-Hosted Umgebung

# docker-compose.selfhosted.yml
version: '3.8'

secrets:
  database_url:
    file: ./secrets/database_url
  jwt_secret:
    file: ./secrets/jwt_secret
  telemetry_push_secret:
    file: ./secrets/telemetry_push_secret

services:
  backend:
    build:
      context: .
      dockerfile: backend-rs/Dockerfile
    container_name: pitwall_backend
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - BACKEND_ADDR=0.0.0.0:3000
      - APP_ENV=production
      - BACKEND_URL=${BACKEND_URL}
      - FRONTEND_URL=${FRONTEND_URL}
      - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}
      - S3_BUCKET_NAME=${S3_BUCKET_NAME:-pitwall-uploads}
      - S3_ENDPOINT=${S3_ENDPOINT:-http://minio:9000}
      - S3_ACCESS_KEY=${S3_ACCESS_KEY}
      - S3_SECRET_KEY=${S3_SECRET_KEY}
      - SENTRY_DSN=${SENTRY_DSN:-}
    secrets:
      - database_url
      - jwt_secret
      - telemetry_push_secret
    depends_on:
      db:
        condition: service_healthy
      minio:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 15s

  db:
    image: postgres:16-alpine
    container_name: pitwall_db
    restart: unless-stopped
    environment:
      - POSTGRES_DB=pitwall_pro
      - POSTGRES_USER=pitwall
      - POSTGRES_PASSWORD_FILE=/run/secrets/database_url
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U pitwall -d pitwall_pro"]
      interval: 5s
      timeout: 5s
      retries: 5

  minio:
    image: minio/minio:latest
    container_name: pitwall_minio
    restart: unless-stopped
    environment:
      - MINIO_ROOT_USER=${MINIO_ROOT_USER:-minioadmin}
      - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioadmin}
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio_data:/data
    command: server /data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 10s
      timeout: 5s
      retries: 5

  minio-init:
    image: minio/mc:latest
    depends_on:
      minio:
        condition: service_healthy
    entrypoint: >
      /bin/sh -c "
      /usr/bin/mc config host add local http://minio:9000 ${MINIO_ROOT_USER:-minioadmin} ${MINIO_ROOT_PASSWORD:-minioadmin} &&
      /usr/bin/mc mb local/pitwall-uploads || true &&
      exit 0
      "

volumes:
  postgres_data:
  minio_data:

3. CI/CD Migration (GitHub Actions zu Forgejo Actions)

3.1 Bestehende Workflows

Workflow Trigger Kern-Jobs
pipeline-backend.yml (308 Z.) Push, PR, Tags v*, manual Unit-Tests + Docker Build + Trivy-Scan + Push zu ghcr.io
pipeline-desktop.yml (631 Z.) Push, PR, Tags v*, manual Cross-Platform Build (Win/macOS), E2E-Tests, Release-Paketierung
pipeline-web.yml (191 Z.) Push, PR, Tags v*, manual WASM-Build + Pen-Tests + Deployment-Platzhalter
build-admin-desktop.yml Push, Tags, manual Cross-Platform Admin-Build
backend-security-performance.yml Nur workflow_dispatch k6-Lasttests + Pen-Tests

3.2 GitHub-spezifische Actions — Kompatibilitätsmatrix

GitHub Action Forgejo Alternative Kompatibilität
actions/checkout@v4 actions/checkout@v4 (forgejo-shipped) Drop-in
dtolnay/rust-toolchain@stable identisch Drop-in
Swatinem/rust-cache@v2 identisch Drop-in
docker/login-action@v3 identisch (andere Registry-URL) Mit Anpassung
docker/build-push-action@v5 identisch Drop-in
docker/metadata-action@v5 identisch Drop-in
aquasecurity/trivy-action@master identisch Drop-in
actions/upload-artifact@v4 actions/upload-artifact@v4 (forgejo) Kompatibel
actions/download-artifact@v4 actions/download-artifact@v4 (forgejo) Kompatibel
actions/cache@v4 actions/cache@v4 (forgejo) Kompatibel
actions/setup-node@v4 identisch Drop-in
actions/setup-python@v5 identisch Drop-in
codecov/codecov-action@v3 Entfällt Durch lokales cargo-tarpaulin ersetzbar
github/codeql-action/upload-sarif@v4 Entfällt Trivy-SARIF lokal speichern
softprops/action-gh-release@v1 Anpassung nötig Durch tea CLI oder Forgejo Release-API ersetzen
GITHUB_TOKEN FORGEJO_TOKEN (äquivalent)
${{ github.repository }} ${{ GITHUB_REPOSITORY }} Drop-in
ghcr.io forgejo.<domain> ⚠️ URL-Anpassung in REGISTRY env

3.3 Forgejo Workflow Entwurf

# .forgejo/workflows/build.yml
name: Backend CI/CD (Forgejo)

on:
  push:
    branches: [ "main", "master", "develop", "feature/**" ]
    paths:
      - 'backend-rs/**'
      - 'core/**'
      - '.forgejo/workflows/build.yml'
    tags:
      - 'v*'
  pull_request:
    branches: [ "main", "master", "develop" ]
  workflow_dispatch:

env:
  REGISTRY: forgejo.pitwall.local
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  build-and-test:
    name: Backend Tests
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_USER: test
          POSTGRES_PASSWORD: test
          POSTGRES_DB: pitwall_test
        ports:
          - 5432:5432

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy, rustfmt

      - name: Install system dependencies
        run: sudo apt-get update && sudo apt-get install -y libasound2-dev

      - name: Cache Dependencies
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: backend-rs

      - name: Install SQLx CLI
        run: cargo install sqlx-cli --no-default-features --features postgres

      - name: Run Database Migrations
        working-directory: backend-rs
        env:
          DATABASE_URL: postgres://test:test@localhost:5432/pitwall_test
        run: sqlx migrate run

      - name: Check Code Formatting
        working-directory: backend-rs
        run: cargo fmt -- --check

      - name: Run Clippy
        working-directory: backend-rs
        run: cargo clippy --all-targets --all-features -- -D warnings

      - name: Run All Tests
        working-directory: backend-rs
        env:
          DATABASE_URL: postgres://test:test@localhost:5432/pitwall_test
          JWT_SECRET: test-secret-for-ci-only
          TELEMETRY_PUSH_SECRET: test-push-secret
        run: cargo test -- --test-threads=1

      - name: Build Project (Release)
        run: cargo build --manifest-path backend-rs/Cargo.toml --release --verbose

  security-scan:
    name: Security Scan (cargo-audit)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Cache dependencies
        uses: Swatinem/rust-cache@v2
        with:
          workspaces: backend-rs

      - name: Install cargo-audit
        run: cargo install cargo-audit --version ^0.20 --locked

      - name: Run cargo audit
        working-directory: backend-rs
        run: cargo audit --deny warnings || true

  publish-docker:
    needs: [build-and-test, security-scan]
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request'

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set lowercase image name
        run: |
          REPO_LOWER=$(echo "${{ GITHUB_REPOSITORY }}" | tr '[:upper:]' '[:lower:]')
          echo "IMAGE_NAME=${REPO_LOWER}-backend-rs" >> $GITHUB_ENV

      - name: Log in to Forgejo Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.FORGEJO_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=ref,event=branch
            type=sha,format=short
            type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: backend-rs/Dockerfile
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

3.4 Notwendige Anpassungen für Forgejo

  1. Registry URL: ghcr.ioforgejo.<deine-domain> in REGISTRY env-Variable
  2. Token: secrets.GITHUB_TOKENsecrets.FORGEJO_TOKEN (in Forgejo automatisch verfügbar)
  3. GitHub Release: softprops/action-gh-release@v1 entfernen — stattdessen tea CLI oder Forgejo Release-API
  4. Codecov/SARIF-Upload: Entfällt ersatzlos oder wird durch lokale Reports ersetzt
  5. Pfad-Filter: paths-Syntax ist in Forgejo Actions kompatibel

4. Ressourcen-Abschätzung (Build-Prozess)

4.1 Ressourcenbedarf pro Build

Komponente RAM (Peak) CPU Build-Zeit (kalt) Build-Zeit (warm, mit Cache)
Backend (Release) ~3–4 GB 100% (single-threaded) ~8–12 Min ~1–2 Min
Desktop-App (Release) ~5–6 GB 100% Multi-Core ~15–25 Min ~3–5 Min
Web-App (WASM Release) ~2–3 GB 100% ~5–8 Min ~1–2 Min
Admin-Desktop (Release) ~2–3 GB 100% ~4–6 Min ~1–2 Min

4.2 Bewertung für Intel Core i3 (4-Core) mit 32 GB RAM — 3 parallele Builds

  • RAM: 32 GB sind ausreichend — selbst 3 parallele Desktop-Builds würden ~15–18 GB benötigen.
  • CPU: 4 Cores sind ausreichend aber begrenzend. CARGO_JOBS=1 ist im Dockerfile gesetzt, was die CPU-Auslastung begrenzt. Empfehlung: CARGO_JOBS=2 oder 3, da 32 GB RAM verfügbar sind.
  • Einschätzung: Der Build-Prozess ist für diese Hardware gut geeignet, insbesondere mit Caching.

4.3 Optimierungspotenzial

Maßnahme Erwartete Verbesserung
cargo-chef für Dependency-Layer-Caching Kaltstart von 8–12 Min auf ~2 Min reduziert
sccache (Shared Compilation Cache) Bis zu 40% schneller bei wiederholten Builds
RAM-Disk für target/ 20–30% schneller I/O
mold Linker statt ld 50–70% schnellere Link-Zeit
Nur relevante Crates bauen --package pitwall-pro-backend-rs (wird bereits gemacht)

Empfohlene Optimierungen für den Forgejo-Workflow:

- name: Configure Cargo for CI
  run: |
    mkdir -p ~/.cargo
    cat >> ~/.cargo/config.toml << EOF
    [target.x86_64-unknown-linux-gnu]
    linker = "clang"
    rustflags = ["-C", "link-arg=-fuse-ld=mold"]
    EOF

- name: Set CARGO_JOBS for 4-core system
  run: echo "CARGO_JOBS=3" >> $GITHUB_ENV

5. Zusammenfassung & Handlungsempfehlung

Machbarkeit: Gut machbar mit moderatem Aufwand

Bereich Bewertung Aufwand
Technologie-Stack Moderner Rust-Stack, gut strukturiert Kein Aufwand
Containerisierung Exzellentes Multi-Stage Dockerfile bereits vorhanden Gering (cargo-chef optional)
12-Factor-App Sehr hohe Konformität Kein Aufwand
CI/CD-Migration ~80% Drop-in kompatibel Mittel (Registry-URL, Token, GitHub-spezifische Actions ersetzen)
Ressourcen i3 + 32 GB ausreichend für 3 parallele Builds Gering
Externe Dienste Nur externe SaaS (Payment, OAuth) — kein Self-Hosting nötig Kein Aufwand

Konkrete nächste Schritte

  1. Forgejo Runner einrichten (Docker-basiert, ubuntu-latest Label)
  2. cargo-chef ins Dockerfile integrieren (spart ~80% Build-Zeit bei Cache-Hits)
  3. .forgejo/workflows/ Verzeichnis mit angepassten Workflows anlegen
  4. Forgejo Container Registry aktivieren und REGISTRY-URL anpassen
  5. Secrets (FORGEJO_TOKEN, DB-Passwörter etc.) in Forgejo hinterlegen
  6. Trivy-Scan beibehalten (ist nicht GitHub-spezifisch)
  7. GitHub Release-Actions durch tea release create oder direkte API-Aufrufe ersetzen
  8. Monitoring-Stack (Prometheus/Grafana) optional mit docker-compose.monitoring.yml hochziehen
# Migration von GitHub zu Forgejo (Self-Hosted) — Machbarkeitsanalyse ## Repository: AISimulate-Engineering/RaceEngineer (Pitwall Pro) **Commit:** `52b28f4` · **Stand:** 07/2026 --- ## 1. Architektur & Abhängigkeiten (Codebasis) ### 1.1 Technologie-Stack | Komponente | Sprache | Framework / Runtime | Build-Output | |---|---|---|---| | **Backend** | Rust (Edition 2021) | Actix-Web (HTTP), SQLx (DB), `tokio` (async) | Native Binary (Linux x86_64) | | **Desktop-App** | Rust + Dioxus | Tauri (GUI), ONNX Runtime (ML), whisper-rs (Speech) | Native Binary (Win/macOS) | | **HUD-Sidecar** | Rust + Tauri | Eigenständiges Fenster für Overlay | Native Binary | | **Admin-Desktop** | Rust + Dioxus | Desktop-Admin-Panel | Native Binary | | **Web-App** | Rust + Dioxus | WASM (wasm32-unknown-unknown), Tailwind CSS | WASM + HTML/JS/CSS | | **Frontend (shared)** | Rust | Dioxus Komponenten-Bibliothek | Library Crate | | **Core (shared)** | Rust | Domain-Logik, Shared Types | Library Crate | | **Common-Client** | Rust | Gemeinsame Client-Logik | Library Crate | | **Altes JVM-Backend** | Kotlin/JVM | Gradle, Ktor | Fat JAR (obsolet) | **Rust-Edition:** 2021 · **Build-System:** Cargo Workspace mit 7 Member-Crates + 1 excluded (`pitwall-hud`) ### 1.2 Abhängigkeitsmanagement - **Rust:** `Cargo.toml` / `Cargo.lock` (alle Crates außer `pitwall-hud` sind Workspace-Members) - **Node.js:** `web-app/package.json` (Tailwind CSS), `package.json` im Root - **Python:** Flask (Mock-Server für E2E-Tests), `huggingface_hub` (Modell-Downloads) - **Gradle:** Nur für das obsolete JVM-Backend ### 1.3 Datenbanken & Services | Service | Zweck | Status | |---|---|---| | **PostgreSQL 16** | Primäre Datenbank (Benutzer, Lizenzen, Sessions, Billing, Telemetrie) | **Kritisch** | | **MinIO / S3-kompatibel** | Telemetrie-Uploads, Track-Baselines, Backups (WAL-G) | **Kritisch für Produktion** | | **Redis 7** | Caching/Sessions (im Test-Compose definiert) | Optional | | **Traefik v2.10** | Reverse-Proxy mit automatischem Let's Encrypt TLS | Produktion | | **Ofelia** | Cron-in-Docker für DB-Backups (pg_dump + wal-g) | Produktion | | **Lemon Squeezy / PayPal** | Externe Zahlungsdienstleister (Billing) | Extern (SaaS) | | **Discord / Google / Microsoft / Steam** | OAuth Social Login | Extern (SaaS) | | **Sentry** | Error-Tracking (optional) | Extern (SaaS) | | **Prometheus + Grafana** | Monitoring (separate Compose-Files vorhanden) | Optional | **Datenbank-Migrationen:** 11 Migrationspaare, verwaltet mit `sqlx-cli`. Kern-Tabellen: `licenses`, `users`, `app_errors`, `track_baselines`, `billing_plans`, `discount_codes`, `system_options`, `sessions`, `telemetry_history`. ### 1.4 Dateisystem-Interaktionen - **Config-Verzeichnis:** `backend-rs/config/` wird relativ zum Binary-Arbeitsverzeichnis aufgelöst — Docker-kompatibel. - **Modelle für ML:** `desktop-app/assets/models/` (ONNX Runtime, Qwen LLM, Kokoro TTS). Zur Build-Zeit eingebettet. - **Persistente Daten:** Alle als Docker-Volumes gemountet — keine harten Pfadabhängigkeiten. - **Secrets:** Docker Secrets (`/run/secrets/<name>`) für Produktion, `.env` für Entwicklung. - **Keine kritischen Hardcoded-Pfade** gefunden. --- ## 2. Containerisierung (Docker-Bereitschaft) ### 2.1 Dockerfile-Analyse | Datei | Bewertung | |---|---| | `backend-rs/Dockerfile` | ✅ **Hervorragend** — 3-Stage-Build, Distroless-Runtime, Non-Root | | `Root Dockerfile` | ⚠️ Obsolet — Kotlin/JVM | | `Dockerfile.test` | ⚠️ Obsolet — JVM-Test-Runner | | `backend-rs/Dockerfile.db` | ✅ Custom PostgreSQL mit wal-g für PITR-Backups | #### `backend-rs/Dockerfile` — detaillierte Bewertung: ``` Stage 1 (builder): rust:bookworm → Kompiliert das Rust-Binary Stage 2 (deps): debian:bookworm-slim → Extrahiert libasound2 Stage 3 (runtime): gcr.io/distroless/cc-debian12:nonroot → Minimal, kein Root ``` **Stärken:** - Multi-Stage Build minimiert Image-Größe - Distroless-Runtime (kein Shell, kein Package-Manager) - Non-Root-User (UID 65532) standardmäßig - Build-Args: `CARGO_JOBS`, `BUILD_MODE` für flexible Builds - `--locked` für reproduzierbare Builds - `CARGO_INCREMENTAL=0`, `LTO=false`, `codegen-units=16` für CI-optimiertes Bauen ### 2.2 12-Factor-App Konformität | Factor | Status | |---|---| | **I. Codebase** | ✅ Ein Monorepo, ein Codebase | | **II. Dependencies** | ✅ Cargo.lock + package-lock.json | | **III. Config** | ✅ Env-Vars + Docker Secrets | | **IV. Backing Services** | ✅ DB/S3 als konfigurierbare Resources | | **V. Build/Release/Run** | ✅ Multi-Stage Dockerfile | | **VI. Processes** | ✅ Stateless Binary | | **VII. Port Binding** | ✅ `BACKEND_ADDR=0.0.0.0:3000` | | **VIII. Concurrency** | ✅ Actix-Web async | | **IX. Disposability** | ✅ Graceful Shutdown via Actix | | **X. Dev/Prod Parity** | ✅ Docker Compose für beide Umgebungen | | **XI. Logs** | ✅ stdout-Logging via `RUST_LOG` / `RUST_LOG_JSON` | | **XII. Admin Processes** | ✅ `sqlx migrate run` als One-Off-Prozess | **Fazit:** Sehr hohe 12-Factor-Konformität. Keine strukturellen Änderungen nötig. ### 2.3 Optimiertes Dockerfile mit cargo-chef ```dockerfile # ─── Stage 0: Cargo Chef (Dependency-Caching) ───────────────────────────── FROM rust:bookworm AS chef RUN cargo install cargo-chef --locked WORKDIR /usr/src/app # ─── Stage 1: Plan (nur Cargo.toml/Cargo.lock für Dependency-Layer) ─────── FROM chef AS planner COPY Cargo.toml Cargo.lock ./ COPY core/Cargo.toml core/ COPY common-client/Cargo.toml common-client/ COPY frontend/Cargo.toml frontend/ COPY backend-rs/Cargo.toml backend-rs/ COPY backend-rs/config backend-rs/config/ RUN mkdir -p core/src common-client/src frontend/src backend-rs/src && \ echo "pub fn dummy() {}" > core/src/lib.rs && \ echo "pub fn dummy() {}" > common-client/src/lib.rs && \ echo "pub fn dummy() {}" > frontend/src/lib.rs && \ echo "fn main() {}" > backend-rs/src/main.rs RUN cargo chef prepare --recipe-path recipe.json # ─── Stage 2: Build Dependencies (cached) ───────────────────────────────── FROM chef AS builder RUN apt-get update && apt-get install -y --no-install-recommends libasound2-dev && \ rm -rf /var/lib/apt/lists/* COPY --from=planner /usr/src/app/recipe.json recipe.json RUN cargo chef cook --release --recipe-path recipe.json COPY . . ARG CARGO_JOBS=1 ARG BUILD_MODE=release ENV CARGO_INCREMENTAL=0 RUN if [ "$BUILD_MODE" = "release" ]; then \ cargo build --release --locked --package pitwall-pro-backend-rs --jobs $CARGO_JOBS; \ else \ cargo build --locked --package pitwall-pro-backend-rs --jobs $CARGO_JOBS; \ fi && \ mkdir -p /app-bin && \ if [ "$BUILD_MODE" = "release" ]; then \ cp target/release/pitwall-pro-backend-rs /app-bin/; \ else \ cp target/debug/pitwall-pro-backend-rs /app-bin/; \ fi # ─── Stage 3: Runtime ───────────────────────────────────────────────────── FROM gcr.io/distroless/cc-debian12:nonroot AS runtime COPY --from=builder /app-bin/pitwall-pro-backend-rs /app/pitwall-pro-backend-rs COPY --from=builder /usr/src/app/backend-rs/config /app/config WORKDIR /app EXPOSE 3000 CMD ["/app/pitwall-pro-backend-rs"] ``` ### 2.4 Docker Compose für Self-Hosted Umgebung ```yaml # docker-compose.selfhosted.yml version: '3.8' secrets: database_url: file: ./secrets/database_url jwt_secret: file: ./secrets/jwt_secret telemetry_push_secret: file: ./secrets/telemetry_push_secret services: backend: build: context: . dockerfile: backend-rs/Dockerfile container_name: pitwall_backend restart: unless-stopped ports: - "3000:3000" environment: - BACKEND_ADDR=0.0.0.0:3000 - APP_ENV=production - BACKEND_URL=${BACKEND_URL} - FRONTEND_URL=${FRONTEND_URL} - ALLOWED_ORIGINS=${ALLOWED_ORIGINS} - S3_BUCKET_NAME=${S3_BUCKET_NAME:-pitwall-uploads} - S3_ENDPOINT=${S3_ENDPOINT:-http://minio:9000} - S3_ACCESS_KEY=${S3_ACCESS_KEY} - S3_SECRET_KEY=${S3_SECRET_KEY} - SENTRY_DSN=${SENTRY_DSN:-} secrets: - database_url - jwt_secret - telemetry_push_secret depends_on: db: condition: service_healthy minio: condition: service_healthy healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"] interval: 10s timeout: 5s retries: 3 start_period: 15s db: image: postgres:16-alpine container_name: pitwall_db restart: unless-stopped environment: - POSTGRES_DB=pitwall_pro - POSTGRES_USER=pitwall - POSTGRES_PASSWORD_FILE=/run/secrets/database_url ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U pitwall -d pitwall_pro"] interval: 5s timeout: 5s retries: 5 minio: image: minio/minio:latest container_name: pitwall_minio restart: unless-stopped environment: - MINIO_ROOT_USER=${MINIO_ROOT_USER:-minioadmin} - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioadmin} ports: - "9000:9000" - "9001:9001" volumes: - minio_data:/data command: server /data --console-address ":9001" healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 10s timeout: 5s retries: 5 minio-init: image: minio/mc:latest depends_on: minio: condition: service_healthy entrypoint: > /bin/sh -c " /usr/bin/mc config host add local http://minio:9000 ${MINIO_ROOT_USER:-minioadmin} ${MINIO_ROOT_PASSWORD:-minioadmin} && /usr/bin/mc mb local/pitwall-uploads || true && exit 0 " volumes: postgres_data: minio_data: ``` --- ## 3. CI/CD Migration (GitHub Actions zu Forgejo Actions) ### 3.1 Bestehende Workflows | Workflow | Trigger | Kern-Jobs | |---|---|---| | `pipeline-backend.yml` (308 Z.) | Push, PR, Tags `v*`, manual | Unit-Tests + Docker Build + Trivy-Scan + Push zu `ghcr.io` | | `pipeline-desktop.yml` (631 Z.) | Push, PR, Tags `v*`, manual | Cross-Platform Build (Win/macOS), E2E-Tests, Release-Paketierung | | `pipeline-web.yml` (191 Z.) | Push, PR, Tags `v*`, manual | WASM-Build + Pen-Tests + Deployment-Platzhalter | | `build-admin-desktop.yml` | Push, Tags, manual | Cross-Platform Admin-Build | | `backend-security-performance.yml` | Nur `workflow_dispatch` | k6-Lasttests + Pen-Tests | ### 3.2 GitHub-spezifische Actions — Kompatibilitätsmatrix | GitHub Action | Forgejo Alternative | Kompatibilität | |---|---|---| | `actions/checkout@v4` | `actions/checkout@v4` (forgejo-shipped) | ✅ Drop-in | | `dtolnay/rust-toolchain@stable` | identisch | ✅ Drop-in | | `Swatinem/rust-cache@v2` | identisch | ✅ Drop-in | | `docker/login-action@v3` | identisch (andere Registry-URL) | ✅ Mit Anpassung | | `docker/build-push-action@v5` | identisch | ✅ Drop-in | | `docker/metadata-action@v5` | identisch | ✅ Drop-in | | `aquasecurity/trivy-action@master` | identisch | ✅ Drop-in | | `actions/upload-artifact@v4` | `actions/upload-artifact@v4` (forgejo) | ✅ Kompatibel | | `actions/download-artifact@v4` | `actions/download-artifact@v4` (forgejo) | ✅ Kompatibel | | `actions/cache@v4` | `actions/cache@v4` (forgejo) | ✅ Kompatibel | | `actions/setup-node@v4` | identisch | ✅ Drop-in | | `actions/setup-python@v5` | identisch | ✅ Drop-in | | `codecov/codecov-action@v3` | ❌ Entfällt | Durch lokales `cargo-tarpaulin` ersetzbar | | `github/codeql-action/upload-sarif@v4` | ❌ Entfällt | Trivy-SARIF lokal speichern | | `softprops/action-gh-release@v1` | ❌ Anpassung nötig | Durch `tea` CLI oder Forgejo Release-API ersetzen | | `GITHUB_TOKEN` | `FORGEJO_TOKEN` (äquivalent) | ✅ | | `${{ github.repository }}` | `${{ GITHUB_REPOSITORY }}` | ✅ Drop-in | | `ghcr.io` | `forgejo.<domain>` | ⚠️ URL-Anpassung in `REGISTRY` env | ### 3.3 Forgejo Workflow Entwurf ```yaml # .forgejo/workflows/build.yml name: Backend CI/CD (Forgejo) on: push: branches: [ "main", "master", "develop", "feature/**" ] paths: - 'backend-rs/**' - 'core/**' - '.forgejo/workflows/build.yml' tags: - 'v*' pull_request: branches: [ "main", "master", "develop" ] workflow_dispatch: env: REGISTRY: forgejo.pitwall.local CARGO_TERM_COLOR: always RUST_BACKTRACE: 1 jobs: build-and-test: name: Backend Tests runs-on: ubuntu-latest services: postgres: image: postgres:16-alpine env: POSTGRES_USER: test POSTGRES_PASSWORD: test POSTGRES_DB: pitwall_test ports: - 5432:5432 steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Rust uses: dtolnay/rust-toolchain@stable with: components: clippy, rustfmt - name: Install system dependencies run: sudo apt-get update && sudo apt-get install -y libasound2-dev - name: Cache Dependencies uses: Swatinem/rust-cache@v2 with: workspaces: backend-rs - name: Install SQLx CLI run: cargo install sqlx-cli --no-default-features --features postgres - name: Run Database Migrations working-directory: backend-rs env: DATABASE_URL: postgres://test:test@localhost:5432/pitwall_test run: sqlx migrate run - name: Check Code Formatting working-directory: backend-rs run: cargo fmt -- --check - name: Run Clippy working-directory: backend-rs run: cargo clippy --all-targets --all-features -- -D warnings - name: Run All Tests working-directory: backend-rs env: DATABASE_URL: postgres://test:test@localhost:5432/pitwall_test JWT_SECRET: test-secret-for-ci-only TELEMETRY_PUSH_SECRET: test-push-secret run: cargo test -- --test-threads=1 - name: Build Project (Release) run: cargo build --manifest-path backend-rs/Cargo.toml --release --verbose security-scan: name: Security Scan (cargo-audit) runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set up Rust uses: dtolnay/rust-toolchain@stable - name: Cache dependencies uses: Swatinem/rust-cache@v2 with: workspaces: backend-rs - name: Install cargo-audit run: cargo install cargo-audit --version ^0.20 --locked - name: Run cargo audit working-directory: backend-rs run: cargo audit --deny warnings || true publish-docker: needs: [build-and-test, security-scan] runs-on: ubuntu-latest if: github.event_name != 'pull_request' steps: - name: Checkout repository uses: actions/checkout@v4 - name: Set lowercase image name run: | REPO_LOWER=$(echo "${{ GITHUB_REPOSITORY }}" | tr '[:upper:]' '[:lower:]') echo "IMAGE_NAME=${REPO_LOWER}-backend-rs" >> $GITHUB_ENV - name: Log in to Forgejo Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.FORGEJO_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=ref,event=branch type=sha,format=short type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' }} - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . file: backend-rs/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} ``` ### 3.4 Notwendige Anpassungen für Forgejo 1. **Registry URL:** `ghcr.io` → `forgejo.<deine-domain>` in `REGISTRY` env-Variable 2. **Token:** `secrets.GITHUB_TOKEN` → `secrets.FORGEJO_TOKEN` (in Forgejo automatisch verfügbar) 3. **GitHub Release:** `softprops/action-gh-release@v1` entfernen — stattdessen `tea` CLI oder Forgejo Release-API 4. **Codecov/SARIF-Upload:** Entfällt ersatzlos oder wird durch lokale Reports ersetzt 5. **Pfad-Filter:** `paths`-Syntax ist in Forgejo Actions kompatibel --- ## 4. Ressourcen-Abschätzung (Build-Prozess) ### 4.1 Ressourcenbedarf pro Build | Komponente | RAM (Peak) | CPU | Build-Zeit (kalt) | Build-Zeit (warm, mit Cache) | |---|---|---|---|---| | **Backend (Release)** | ~3–4 GB | 100% (single-threaded) | ~8–12 Min | ~1–2 Min | | **Desktop-App (Release)** | ~5–6 GB | 100% Multi-Core | ~15–25 Min | ~3–5 Min | | **Web-App (WASM Release)** | ~2–3 GB | 100% | ~5–8 Min | ~1–2 Min | | **Admin-Desktop (Release)** | ~2–3 GB | 100% | ~4–6 Min | ~1–2 Min | ### 4.2 Bewertung für Intel Core i3 (4-Core) mit 32 GB RAM — 3 parallele Builds - **RAM:** 32 GB sind **ausreichend** — selbst 3 parallele Desktop-Builds würden ~15–18 GB benötigen. - **CPU:** 4 Cores sind **ausreichend aber begrenzend**. `CARGO_JOBS=1` ist im Dockerfile gesetzt, was die CPU-Auslastung begrenzt. Empfehlung: `CARGO_JOBS=2` oder `3`, da 32 GB RAM verfügbar sind. - **Einschätzung:** Der Build-Prozess ist für diese Hardware **gut geeignet**, insbesondere mit Caching. ### 4.3 Optimierungspotenzial | Maßnahme | Erwartete Verbesserung | |---|---| | **`cargo-chef` für Dependency-Layer-Caching** | Kaltstart von 8–12 Min auf ~2 Min reduziert | | **`sccache` (Shared Compilation Cache)** | Bis zu 40% schneller bei wiederholten Builds | | **RAM-Disk für `target/`** | 20–30% schneller I/O | | **`mold` Linker statt `ld`** | 50–70% schnellere Link-Zeit | | **Nur relevante Crates bauen** | `--package pitwall-pro-backend-rs` (wird bereits gemacht) | **Empfohlene Optimierungen für den Forgejo-Workflow:** ```yaml - name: Configure Cargo for CI run: | mkdir -p ~/.cargo cat >> ~/.cargo/config.toml << EOF [target.x86_64-unknown-linux-gnu] linker = "clang" rustflags = ["-C", "link-arg=-fuse-ld=mold"] EOF - name: Set CARGO_JOBS for 4-core system run: echo "CARGO_JOBS=3" >> $GITHUB_ENV ``` --- ## 5. Zusammenfassung & Handlungsempfehlung ### Machbarkeit: ✅ **Gut machbar mit moderatem Aufwand** | Bereich | Bewertung | Aufwand | |---|---|---| | **Technologie-Stack** | Moderner Rust-Stack, gut strukturiert | Kein Aufwand | | **Containerisierung** | Exzellentes Multi-Stage Dockerfile bereits vorhanden | Gering (cargo-chef optional) | | **12-Factor-App** | Sehr hohe Konformität | Kein Aufwand | | **CI/CD-Migration** | ~80% Drop-in kompatibel | Mittel (Registry-URL, Token, GitHub-spezifische Actions ersetzen) | | **Ressourcen** | i3 + 32 GB ausreichend für 3 parallele Builds | Gering | | **Externe Dienste** | Nur externe SaaS (Payment, OAuth) — kein Self-Hosting nötig | Kein Aufwand | ### Konkrete nächste Schritte 1. **Forgejo Runner einrichten** (Docker-basiert, `ubuntu-latest` Label) 2. **`cargo-chef`** ins Dockerfile integrieren (spart ~80% Build-Zeit bei Cache-Hits) 3. **`.forgejo/workflows/`** Verzeichnis mit angepassten Workflows anlegen 4. **Forgejo Container Registry** aktivieren und `REGISTRY`-URL anpassen 5. **Secrets** (`FORGEJO_TOKEN`, DB-Passwörter etc.) in Forgejo hinterlegen 6. **Trivy-Scan** beibehalten (ist nicht GitHub-spezifisch) 7. **GitHub Release-Actions** durch `tea release create` oder direkte API-Aufrufe ersetzen 8. **Monitoring-Stack** (Prometheus/Grafana) optional mit `docker-compose.monitoring.yml` hochziehen
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thomas_knaus/RaceEngineer#139
No description provided.