Erster - Push für Zora
This commit is contained in:
@@ -0,0 +1,118 @@
|
|||||||
|
name: Build and Publish Docker Images
|
||||||
|
run-name: Build & Publish by @${{ github.actor }}
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
paths:
|
||||||
|
- 'backend/**'
|
||||||
|
- 'platform/**'
|
||||||
|
- 'core/**'
|
||||||
|
- 'frontend/**'
|
||||||
|
- 'config/docker/**'
|
||||||
|
- 'build.gradle.kts'
|
||||||
|
- 'settings.gradle.kts'
|
||||||
|
- 'gradle.properties'
|
||||||
|
- 'docker-compose.yaml'
|
||||||
|
- '.gitea/workflows/docker-publish.yaml'
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: git.mo-code.at
|
||||||
|
IMAGE_PREFIX: mo-code/meldestelle
|
||||||
|
# Build Arguments
|
||||||
|
GRADLE_VERSION: "8.5"
|
||||||
|
JAVA_VERSION: "21"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- service: api-gateway
|
||||||
|
context: .
|
||||||
|
dockerfile: backend/infrastructure/gateway/Dockerfile
|
||||||
|
image: gateway
|
||||||
|
- service: ping-service
|
||||||
|
context: .
|
||||||
|
dockerfile: backend/services/ping/Dockerfile
|
||||||
|
image: ping-service
|
||||||
|
- service: web-app
|
||||||
|
context: .
|
||||||
|
dockerfile: config/docker/caddy/web-app/Dockerfile
|
||||||
|
image: web-app
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Java Setup für den Frontend Build (Gradle braucht Java)
|
||||||
|
- name: Set up JDK 21
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: '21'
|
||||||
|
distribution: 'temurin'
|
||||||
|
|
||||||
|
# Cache für Gradle
|
||||||
|
- name: Setup Gradle Cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.gradle/caches
|
||||||
|
~/.gradle/wrapper
|
||||||
|
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-gradle-
|
||||||
|
|
||||||
|
# Frontend Build (nur für web-app)
|
||||||
|
# Baut die statischen Dateien, die das Dockerfile dann per COPY reinzieht
|
||||||
|
- name: Build Frontend (Kotlin JS)
|
||||||
|
if: matrix.service == 'web-app'
|
||||||
|
run: |
|
||||||
|
chmod +x gradlew
|
||||||
|
./gradlew :frontend:shells:meldestelle-portal:jsBrowserDistribution -Pproduction=true --no-daemon
|
||||||
|
|
||||||
|
# QEMU für Multi-Arch Support (ARM64 + AMD64)
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
# Docker Buildx für erweiterten Build-Support
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
# Login bei der Gitea Registry
|
||||||
|
- name: Log in to the Container registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ secrets.REGISTRY_USER }}
|
||||||
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
# Metadaten extrahieren (Tags, Labels)
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.image }}
|
||||||
|
tags: |
|
||||||
|
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
|
type=sha,format=long
|
||||||
|
|
||||||
|
# Build und Push
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: ${{ matrix.context }}
|
||||||
|
file: ${{ matrix.dockerfile }}
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
build-args: |
|
||||||
|
DOCKER_BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
VERSION=${{ github.sha }}
|
||||||
|
GRADLE_VERSION=${{ env.GRADLE_VERSION }}
|
||||||
|
JAVA_VERSION=${{ env.JAVA_VERSION }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
# syntax=docker/dockerfile:1.8
|
# syntax=docker/dockerfile:1.8
|
||||||
|
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
# Dockerfile for Meldestelle Web-App (Hybrid Build)
|
# Dockerfile for Meldestelle Web-App (Hybrid Build)
|
||||||
# Version: 3.2.0 - Optimized & Cleaned
|
# Version: 3.2.0 - Optimized & Cleaned
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ services:
|
|||||||
|
|
||||||
# --- API-GATEWAY: Spring Cloud Gateway ---
|
# --- API-GATEWAY: Spring Cloud Gateway ---
|
||||||
api-gateway:
|
api-gateway:
|
||||||
|
image: "${DOCKER_REGISTRY:-git.mo-code.at/mo-code}/meldestelle-gateway:${DOCKER_TAG:-latest}"
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: backend/infrastructure/gateway/Dockerfile
|
dockerfile: backend/infrastructure/gateway/Dockerfile
|
||||||
@@ -78,6 +79,7 @@ services:
|
|||||||
|
|
||||||
# --- MICROSERVICE: Ping Service ---
|
# --- MICROSERVICE: Ping Service ---
|
||||||
ping-service:
|
ping-service:
|
||||||
|
image: "${DOCKER_REGISTRY:-git.mo-code.at/mo-code}/meldestelle-ping-service:${DOCKER_TAG:-latest}"
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: backend/services/ping/Dockerfile
|
dockerfile: backend/services/ping/Dockerfile
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ services:
|
|||||||
|
|
||||||
# --- WEB-APP ---
|
# --- WEB-APP ---
|
||||||
web-app:
|
web-app:
|
||||||
|
image: "${DOCKER_REGISTRY:-git.mo-code.at/mo-code}/meldestelle-web-app:${DOCKER_TAG:-latest}"
|
||||||
build:
|
build:
|
||||||
context: . # Wichtig: Root Context für Monorepo Zugriff
|
context: . # Wichtig: Root Context für Monorepo Zugriff
|
||||||
dockerfile: config/docker/caddy/web-app/Dockerfile
|
dockerfile: config/docker/caddy/web-app/Dockerfile
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# SSoT Konfigurations-Masterplan für Zora (ARM64)
|
||||||
|
|
||||||
|
## 1. System-Umgebung (Infrastruktur)
|
||||||
|
| Parameter | Wert | Erklärung |
|
||||||
|
|:-------------------|:--------------|:-------------------------------------------------|
|
||||||
|
| **Architektur** | `linux/arm64` | Native Architektur von Zora (Host). |
|
||||||
|
| **Host-IP (Zora)** | `10.0.6.1` | Gateway für alle Container (Bridge `incusbr0`). |
|
||||||
|
| **Projekt-IP** | `10.0.6.50` | Feste IP für den Docker-Host `prod-meldestelle`. |
|
||||||
|
| **DNS-Server** | `10.0.6.1` | Zora übernimmt die Namensauflösung. |
|
||||||
|
|
||||||
|
## 2. Mail-Relay (SSoT Identity)
|
||||||
|
Diese Daten müssen in der Spring Boot `application.yml` oder `.env` abgeglichen werden.
|
||||||
|
* **SMTP-Host:** `10.0.6.1` (Zora Host Relay)
|
||||||
|
* **SMTP-Port:** `25` (Passwortloser interner Zugriff via `mynetworks`)
|
||||||
|
* **Absender:** `zora@mo-code.at` (Verifizierte World4You Identität)
|
||||||
|
|
||||||
|
## 3. Docker-Image Checkliste (ARM64 Kompatibilität)
|
||||||
|
Bitte prüfe in deinen `docker-compose.yaml` Dateien, ob diese Images genutzt werden (alle unterstützen offiziell ARM64):
|
||||||
|
|
||||||
|
| Dienst | Empfohlenes Image | Status |
|
||||||
|
|:---------------|:---------------------------------|:-----------------------------------------------|
|
||||||
|
| **Datenbank** | `postgres:15-alpine` | ARM64 Support: Ja |
|
||||||
|
| **Cache** | `valkey/valkey:8-alpine` | ARM64 Support: Ja (Besserer Support als Redis) |
|
||||||
|
| **Identity** | `quay.io/keycloak/keycloak:24.0` | ARM64 Support: Ja (Offiziell) |
|
||||||
|
| **Monitoring** | `prom/prometheus:latest` | ARM64 Support: Ja |
|
||||||
|
| **Dashboards** | `grafana/grafana:latest` | ARM64 Support: Ja |
|
||||||
|
|
||||||
|
## 4. Backend & Gateway (Spring Boot)
|
||||||
|
Da du diese selbst baust, ist die Dockerfile-Konfiguration entscheidend:
|
||||||
|
|
||||||
|
* **Base Image:** Nutze `eclipse-temurin:17-jre-alpine` oder `21-jre-alpine`. Diese sind für ARM64 optimiert.
|
||||||
|
* **Build-Prozess:** Dein Gitea-Runner auf Zora baut automatisch für ARM64, da er auf der gleichen Hardware läuft.
|
||||||
|
|
||||||
|
## 5. Keycloak SSoT Integration
|
||||||
|
Wichtige Endpunkte für deine Microservices in der IDEA:
|
||||||
|
* **External Issuer:** `https://auth.mo-code.at/realms/mocode-realm`
|
||||||
|
* **Internal Issuer:** `http://infra-keycloak:8080/realms/mocode-realm` (Für die Kommunikation innerhalb des Docker-Netzwerks)
|
||||||
|
* **Client-ID:** `meldestelle-client`
|
||||||
|
|
||||||
|
## 6. Cloudflare Tunnel Routing
|
||||||
|
Stelle sicher, dass deine Ingress-Rules auf die IP der Meldestelle zeigen:
|
||||||
|
* `api.mo-code.at` -> `http://10.0.6.50:8080` (Gateway)
|
||||||
|
* `auth.mo-code.at` -> `http://10.0.6.50:8180` (Keycloak)
|
||||||
|
* `git.mo-code.at` -> `http://10.0.6.100:3000` (Gitea LXC - bereits aktiv)
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# Dokumentation: Zentrales Mail-Relay (SSoT) auf Zora
|
||||||
|
|
||||||
|
## 1. Identität & Rollenverteilung
|
||||||
|
Das System nutzt das **Single Source of Truth (SSoT)** Prinzip für den gesamten E-Mail-Verkehr. Anstatt dass jeder Dienst (Gitea, Keycloak, Spring Boot) eigene Zugangsdaten für World4You speichert, übernimmt **Zora** die zentrale Verwaltung.
|
||||||
|
|
||||||
|
| Parameter | Wert | Funktion |
|
||||||
|
|:-------------------|:-------------------------|:-------------------------------------------------|
|
||||||
|
| **Zentraler Host** | `zora.mo-code.at` | Primärer Mail-Transfer-Agent (MTA). |
|
||||||
|
| **Gateway IP** | `10.0.6.1` | Interne Erreichbarkeit für alle Container/VMs. |
|
||||||
|
| **Relay Host** | `smtp.world4you.com:587` | Externer Provider für den tatsächlichen Versand. |
|
||||||
|
| **SSoT Account** | `zora@mo-code.at` | Die verifizierte Absender-Identität. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Technische Umsetzung (Der "Postbote")
|
||||||
|
Wir haben Postfix als **Satellitensystem** konfiguriert. Er nimmt Briefe im internen Netzwerk entgegen und bringt sie sicher zum Provider.
|
||||||
|
|
||||||
|
* **Sicherheit:** Postfix lauscht auf Port 25, erlaubt den Versand aber **nur** für Anfragen aus dem internen Netz `10.0.0.0/8` (Incus/Docker).
|
||||||
|
* **Authentifizierung:** Nur Zora kennt das Passwort für den World4You-Account (gespeichert in `sasl_passwd`).
|
||||||
|
* **Umschreibung (Canonical Mapping):** Postfix korrigiert automatisch Absender wie `root@zora` oder `grandmo@zora` zu `zora@mo-code.at`, damit der Provider die Mails nicht ablehnt.
|
||||||
|
* **Verschlüsselung:** Die Verbindung zu World4You ist via TLS (STARTTLS) abgesichert.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Vorstellung: Der Benachrichtigungs-Weg
|
||||||
|
Unsere Vision für den "Empire-Workflow" sieht wie folgt aus:
|
||||||
|
|
||||||
|
### Phase A: Das Ereignis (Trigger)
|
||||||
|
Ein Dienst stellt einen Zustand fest, der gemeldet werden muss.
|
||||||
|
* **Gitea:** Ein neuer Pull Request wurde erstellt.
|
||||||
|
* **Prometheus/Alertmanager:** Die Festplatte von Zora ist zu 90% voll.
|
||||||
|
* **Spring Boot:** Ein User hat sein Passwort für die "Meldestelle" vergessen.
|
||||||
|
|
||||||
|
### Phase B: Der interne Transport
|
||||||
|
Der Dienst verbindet sich ohne Passwort (da er sich im vertrauenswürdigen Netz befindet) mit:
|
||||||
|
`SMTP_HOST: 10.0.6.1` | `SMTP_PORT: 25`
|
||||||
|
Dies minimiert das Risiko: Keine Passwörter in `.env`-Dateien von Applikationen.
|
||||||
|
|
||||||
|
### Phase C: Die externe Zustellung
|
||||||
|
Zora nimmt die Mail an, prüft sie, fügt ggf. die korrekte Absenderadresse hinzu und reicht sie an World4You weiter. Von dort landet sie in deinem Gmail-Postfach.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Status Quo (Erfolgskontrolle)
|
||||||
|
Dass dieser Weg bereits perfekt funktioniert, wurde durch die Gitea Test-Email am **10.02.2026 um 00:56 Uhr** bewiesen. Die Mail kam sauber signiert und verschlüsselt an.
|
||||||
Reference in New Issue
Block a user