name: 🚀 Docker Image Build & Security Scan on: push: branches: - main - beta - alpha - Nachweise workflow_dispatch: # Manueller Trigger schedule: # Täglicher Security-Scan um 6:00 UTC - cron: '0 6 * * *' env: # ⚠️ ANPASSEN: Nur die Registry-URL anpassen REGISTRY: git.csnetworkx.dev # Image-Name wird automatisch aus Repository generiert: REGISTRY/owner/repo # Beispiel: git.csnetworkx.dev/user/project TRIVY_VERSION: 0.58.1 jobs: # 🔍 Security-Scan des Quellcodes und der Abhängigkeiten security-scan: name: 🔍 Sicherheitsüberprüfung runs-on: ubuntu-latest steps: - name: 📥 Repository auschecken uses: actions/checkout@v4 - name: 🔧 Trivy installieren run: | echo "📦 Installiere Trivy Security Scanner..." # Moderne Installation ohne deprecated apt-key wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/trivy-archive-keyring.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list sudo apt-get update sudo apt-get install -y trivy trivy --version - name: 🔍 Quellcode & Abhängigkeiten scannen run: | echo "🔍 Scanne Quellcode und npm-Abhängigkeiten..." trivy fs --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed . - name: 🔍 Dockerfile & Konfiguration scannen run: | echo "🔍 Scanne Dockerfile und IaC-Konfigurationen..." # Erzwinge auch kleingeschriebene Dockerfiles (z.B. ./dockerfile) trivy config --severity CRITICAL,HIGH --exit-code 1 \ --file-patterns "dockerfile:.*[Dd]ockerfile.*" . # 🔄 Täglicher Scan und automatische Fixes (nur bei scheduled runs) daily-security-scan: name: 🔄 Täglicher Security-Scan & Auto-Fix runs-on: ubuntu-latest if: github.event_name == 'schedule' steps: - name: 📥 Repository auschecken (main Branch) uses: actions/checkout@v4 with: ref: main - name: 🏷️ Image-Namen generieren id: image_name run: | # Generiere Image-Name: REGISTRY/repository-lowercase # Gitea: nutze GITHUB_REPOSITORY oder GITEA_REPOSITORY REPO="${GITHUB_REPOSITORY:-$GITEA_REPOSITORY}" IMAGE="${{ env.REGISTRY }}/${REPO}" IMAGE_LOWER=$(echo "$IMAGE" | tr '[:upper:]' '[:lower:]') echo "image=${IMAGE_LOWER}" >> "$GITHUB_OUTPUT" echo "✅ Image-Name: ${IMAGE_LOWER}" echo "📦 Repository: ${REPO}" - name: 🟢 Node.js einrichten uses: actions/setup-node@v4 with: node-version: '20' - name: 🔧 Trivy installieren run: | echo "📦 Installiere Trivy Security Scanner..." # Moderne Installation ohne deprecated apt-key wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/trivy-archive-keyring.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list sudo apt-get update sudo apt-get install -y trivy trivy --version - name: 🔐 In Docker Registry einloggen uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: 🔍 Docker Image scannen (latest) id: image_scan continue-on-error: true run: | echo "🐳 Scanne Docker Image: ${{ steps.image_name.outputs.image }}:latest" trivy image --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed ${{ steps.image_name.outputs.image }}:latest || echo "scan_failed=true" >> "$GITHUB_OUTPUT" - name: 🔍 Dateisystem scannen id: fs_scan continue-on-error: true run: | echo "📁 Scanne Dateisystem und Abhängigkeiten..." trivy fs --severity CRITICAL,HIGH --exit-code 1 --ignore-unfixed . || echo "scan_failed=true" >> "$GITHUB_OUTPUT" - name: 🔧 npm audit fix ausführen (Frontend) if: steps.fs_scan.outcome == 'failure' working-directory: ./frontend run: | echo "🔧 Führe npm audit fix aus (Frontend)..." npm audit fix --force || true npm update || true - name: 🔧 npm audit fix ausführen (Backend) if: steps.fs_scan.outcome == 'failure' working-directory: ./backend run: | echo "🔧 Führe npm audit fix aus (Backend)..." npm audit fix --force || true npm update || true - name: 🔎 Änderungen prüfen id: changes run: | if git diff --quiet; then echo "has_changes=false" >> "$GITHUB_OUTPUT" echo "✅ Keine Änderungen durch npm audit fix" else echo "has_changes=true" >> "$GITHUB_OUTPUT" echo "📝 Änderungen wurden vorgenommen" fi - name: 💾 Änderungen committen & pushen if: steps.changes.outputs.has_changes == 'true' run: | echo "💾 Committe automatische Security-Fixes..." git config user.name "Security Bot" git config user.email "security-bot@csnetworkx.dev" git add -A git commit -m "🔒 Security: Automatische Dependency-Updates [skip ci] - npm audit fix ausgeführt - Schwachstellen in Abhängigkeiten behoben 🤖 Automatisch generiert durch den täglichen Security-Scan Der Build wird beim nächsten manuellen Push ausgeführt." git push - name: 🔨 Docker Buildx einrichten if: steps.image_scan.outcome == 'failure' || steps.changes.outputs.has_changes == 'true' uses: docker/setup-buildx-action@v3 - name: 🏗️ Docker Image neu bauen & pushen if: steps.image_scan.outcome == 'failure' || steps.changes.outputs.has_changes == 'true' uses: docker/build-push-action@v5 with: context: . push: true pull: true # Zieht immer das neueste Base-Image build-args: | VERSION_TAG=latest VERSION_SHA=${{ github.sha }} tags: ${{ steps.image_name.outputs.image }}:latest - name: 📊 Security-Report erstellen if: always() run: | echo "╔════════════════════════════════════════╗" echo "║ 🔒 SECURITY SCAN REPORT 🔒 ║" echo "╚════════════════════════════════════════╝" echo "" echo "📋 Scan-Ergebnisse:" echo " • Docker Image: ${{ steps.image_scan.outcome }}" echo " • Dateisystem: ${{ steps.fs_scan.outcome }}" echo " • Änderungen: ${{ steps.changes.outputs.has_changes }}" echo "" if [[ "${{ steps.image_scan.outcome }}" == "failure" ]] || [[ "${{ steps.fs_scan.outcome }}" == "failure" ]]; then echo "⚠️ SCHWACHSTELLEN GEFUNDEN!" if [[ "${{ steps.changes.outputs.has_changes }}" == "true" ]]; then echo "✅ Automatische Fixes wurden angewendet und committed." else echo "❌ Keine automatischen Fixes möglich - manuelle Überprüfung erforderlich!" fi else echo "✅ Keine kritischen Schwachstellen gefunden." fi echo "" # 🐳 Docker Image bauen und pushen docker-build-and-push: name: 🐳 Docker Image Build & Push runs-on: ubuntu-latest needs: security-scan if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && needs.security-scan.result == 'success' steps: - name: 📥 Repository auschecken uses: actions/checkout@v4 - name: 🏷️ Image-Namen & Tags berechnen id: vars shell: bash run: | # Generiere Image-Name aus Repository (lowercase) # Gitea: nutze GITHUB_REPOSITORY oder GITEA_REPOSITORY REPO="${GITHUB_REPOSITORY:-$GITEA_REPOSITORY}" IMAGE="${{ env.REGISTRY }}/${REPO}" IMAGE_LOWER=$(echo "$IMAGE" | tr '[:upper:]' '[:lower:]') echo "image_name=${IMAGE_LOWER}" >> "$GITHUB_OUTPUT" echo "✅ Image-Name: ${IMAGE_LOWER}" echo "📦 Repository: ${REPO}" # Berechne Branch-Tag (Gitea kompatibel) BRANCH="${GITHUB_REF_NAME:-$GITEA_REF_NAME}" echo "🏷️ Berechne Image-Tags für Branch: ${BRANCH}" case "${BRANCH}" in main) echo "branch_tag=latest" >> "$GITHUB_OUTPUT" ;; beta) echo "branch_tag=beta" >> "$GITHUB_OUTPUT" ;; alpha) echo "branch_tag=alpha" >> "$GITHUB_OUTPUT" ;; Nachweise) echo "branch_tag=Nachweise" >> "$GITHUB_OUTPUT" ;; *) echo "branch_tag=${BRANCH}" >> "$GITHUB_OUTPUT" ;; esac # SHA (Gitea kompatibel) SHA="${GITHUB_SHA:-$GITEA_SHA}" echo "short_sha=${SHA::8}" >> "$GITHUB_OUTPUT" echo "✅ Branch-Tag: $(cat $GITHUB_OUTPUT | grep branch_tag | cut -d'=' -f2)" echo "✅ SHA-Tag: ${SHA::8}" - name: 🖥️ QEMU einrichten (Multi-Arch Support) uses: docker/setup-qemu-action@v3 - name: 🔨 Docker Buildx einrichten uses: docker/setup-buildx-action@v3 - name: 🔌 Registry-Verbindung testen run: | echo "🔌 Teste Verbindung zur Registry: ${{ env.REGISTRY }}" echo "" echo "1️⃣ HTTP-Verbindungstest..." curl -v --connect-timeout 10 https://${{ env.REGISTRY }}/v2/ || echo "⚠️ Curl fehlgeschlagen" echo "" echo "2️⃣ DNS-Auflösung..." nslookup ${{ env.REGISTRY }} || echo "⚠️ DNS-Lookup fehlgeschlagen" echo "" echo "3️⃣ Netzwerk-Ping..." ping -c 3 ${{ env.REGISTRY }} || echo "⚠️ Ping fehlgeschlagen" - name: 🔐 Manueller Login-Test run: | echo "🔐 Teste manuellen Docker-Login..." echo ${{ secrets.DOCKER_PASSWORD }} | docker login --username ${{ secrets.DOCKER_USERNAME }} --password-stdin ${{ env.REGISTRY }} echo "✅ Login erfolgreich!" - name: 🔐 In Docker Registry einloggen uses: docker/login-action@v3 env: DOCKER_CLI_DEBUG: 1 with: registry: ${{ env.REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: 🏗️ Docker Image bauen & pushen uses: docker/build-push-action@v5 with: context: . push: true platforms: linux/amd64,linux/arm64 build-args: | VERSION_TAG=${{ steps.vars.outputs.branch_tag }} VERSION_SHA=${{ steps.vars.outputs.short_sha }} tags: | ${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.branch_tag }} ${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.short_sha }} - name: ✅ Build-Zusammenfassung if: success() run: | echo "╔════════════════════════════════════════╗" echo "║ ✅ BUILD ERFOLGREICH ✅ ║" echo "╚════════════════════════════════════════╝" echo "" echo "📦 Gebaute Images:" echo " • ${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.branch_tag }}" echo " • ${{ steps.vars.outputs.image_name }}:${{ steps.vars.outputs.short_sha }}" echo "" echo "🎯 Plattformen: linux/amd64, linux/arm64" echo "📤 Erfolgreich in Registry gepusht!" echo "" echo "🏷️ Image-Name: ${{ steps.vars.outputs.image_name }}" echo "📍 Registry: ${{ env.REGISTRY }}" echo "🔗 Repository: ${GITHUB_REPOSITORY:-$GITEA_REPOSITORY}" echo ""