No description
  • PowerShell 90.4%
  • Shell 4.6%
  • Python 4.1%
  • HTML 0.7%
  • Dockerfile 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-09-27 09:50:47 +02:00
.claude moved mediathek test from app-1 to app-4 2026-06-30 11:14:27 +02:00
applications Move Lano deployment to app-5 and add verifiable storage migration tools 2026-09-27 00:02:44 +02:00
assets added default nginx error page 2026-06-10 15:09:33 +02:00
docs Record verified Gotenberg upgrade and retained rollback 2026-09-27 09:50:47 +02:00
infrastructure/gotenberg Enable Debian contrib for existing Microsoft core fonts 2026-09-27 09:48:11 +02:00
scripts Pin Gotenberg 8.37 and document verified converter updates 2026-09-27 09:47:19 +02:00
yeet-deps "yeet" 2025-07-11 22:17:02 +02:00
.gitignore Ignore explicitly authorized local credential file 2026-09-06 00:03:33 +02:00
Add-AuraCustomerCostAllocation.ps1 Update deploy tooling and Aura reports 2026-03-31 20:56:59 +02:00
Add-AuraTokenUsageCostComparison.ps1 Update deploy tooling and Aura reports 2026-03-31 20:56:59 +02:00
Add-AuraTokenUsageMonthlyShare.ps1 Update deploy tooling and Aura reports 2026-03-31 20:56:59 +02:00
AGENTS.md Standardize AURA dependency superset and repeatable host provisioning 2026-09-27 03:12:44 +02:00
CLAUDE.md updated slow log documentation 2026-09-22 09:12:21 +02:00
create-app-4-5-db-users.sql Updated documentation and added app-1 split 2026-06-25 14:23:06 +02:00
Create-Or-Update-Certificate.ps1 feat: Refactor deployment scripts and update documentation 2025-07-09 22:30:43 +02:00
Deploy-Application.ps1 Retain three deployment backups and Beam releases 2026-09-25 04:01:59 +02:00
env.template Document app-6 bootstrap and include required SDK 2026-09-27 02:50:58 +02:00
ExecuteRemoteCommand.ps1 Add app-6 to Linode deployment and bootstrap tooling 2026-09-27 02:45:00 +02:00
FetchRemoteMemoryDump.ps1 Add backup/restore feature for deployments and memory dump tool 2026-01-05 18:08:13 +01:00
Get-AuraTokenUsageReport.ps1 Update deploy tooling and Aura reports 2026-03-31 20:56:59 +02:00
Get-ServerInfo.ps1 feat: Refactor deployment scripts and update documentation 2025-07-09 22:30:43 +02:00
grant_aura_permissions.sql gbn/wia mandant 2025-11-18 08:01:07 +01:00
Initialize-AuraHost.ps1 Standardize AURA dependency superset and repeatable host provisioning 2026-09-27 03:12:44 +02:00
Initialize-Nginx.ps1 Nginx - Große AURA-ZIP-Uploads zulassen 2026-09-04 18:47:33 +02:00
Initialize-YeetUsers.ps1 Fail fast in host bootstrap and align maintenance documentation 2026-09-27 03:16:14 +02:00
Install-Dependencies.ps1 "yeet" 2025-07-11 22:17:02 +02:00
LinodeUtils.psm1 Add app-6 to Linode deployment and bootstrap tooling 2026-09-27 02:45:00 +02:00
MIGRATION_PLAN_AURA.md Add TargetServer field to all app configs and show in yeet TUI 2026-01-18 19:47:17 +01:00
nginx.md SkipBuild/SkipCleanup entfernt, Deploy-Dokumentation verbessert 2026-02-18 15:36:18 +01:00
README.md Record verified Gotenberg upgrade and retained rollback 2026-09-27 09:50:47 +02:00
Repair-NginxConfigs.ps1 Update deploy tooling and Aura reports 2026-03-31 20:56:59 +02:00
serverstatus.sh feat: Refactor deployment scripts and update documentation 2025-07-09 22:30:43 +02:00
Set-LinodeVpcInterface.ps1 Preserve Linode swap disk and handle interface list response 2026-09-27 02:48:49 +02:00
Setup-YeetDeployment.ps1 Add app-6 to Linode deployment and bootstrap tooling 2026-09-27 02:45:00 +02:00
Upload-Diagnostics.ps1 pspp hostkey 2025-07-10 12:04:43 +02:00
yeet.ps1 SkipBuild/SkipCleanup entfernt, Deploy-Dokumentation verbessert 2026-02-18 15:36:18 +01:00

Linode Server Deployment System 🚀

Automatisiertes Deployment-System für .NET Anwendungen auf Linode Servern mit PowerShell und Linux systemd Services.

📖 New here? Read docs/yeet-system.md for a conceptual overview of how the whole Yeet system works (architecture, auth model, deployment lifecycle, networking, data layer). This README is the quick start + app catalog.

Yeet - Das einfache Deployment-Tool 🎯

Yeet ist ein interaktives Terminal-UI (TUI) Tool, das den Deployment-Prozess vereinfacht. Statt komplexe PowerShell-Befehle zu tippen, können Sie Anwendungen über eine benutzerfreundliche Menü-Oberfläche auswählen und deployen.

Was macht Yeet?

  • Interaktive Navigation: Durchsucht automatisch den applications/ Ordner und zeigt alle deploybare Anwendungen in einer hierarchischen Menüstruktur
  • Server-Anzeige: Zeigt den Zielserver für jede App in Klammern an (z.B. ProdErfalAdminPortal [aturis-app-1])
  • ASCII-Art Interface: Stilvolles Terminal-UI mit gelbem "YEET" Banner
  • Sound-Effekte: Spielt einen Deployment-Sound beim Start eines Deployments
  • Ein-Klick Deployment: Wählen Sie einfach eine Anwendung aus und Yeet kümmert sich um den Rest

Wie benutzt man Yeet?

  1. Erstmalige Einrichtung (nur einmal nötig):

    .\Install-Dependencies.ps1
    

    Dies installiert die benötigten PowerShell-Module und richtet den yeet Alias ein.

  2. Einrichtung der SSH-Schlüssel (Kann beliebig oft wiederholt werden):

    Das Setup-Skript erstellt automatisch einen SSH-Schlüssel, akzeptiert die Server-Hostschlüssel und richtet den Key auf beiden App-Servern ein. Es sind keine manuellen Schritte nötig:

    .\Setup-YeetDeployment.ps1
    
  3. Yeet starten:

    yeet
    

    Oder direkt:

    .\yeet.ps1
    
  4. Navigation:

    • ↑/↓ - Durch die Liste navigieren
    • Enter - Ordner öffnen oder Anwendung deployen
    • ESC - Zurück zur vorherigen Ebene
    • Q - Beenden

Das Tool führt im Hintergrund Deploy-Application.ps1 mit der ausgewählten Anwendung aus und zeigt den Deployment-Fortschritt in einem separaten Fenster an.

📋 Unterstützte Anwendungen

Das Deployment-System unterstützt alle Mediathek-Anwendungen in Test- und Produktionsumgebungen. Jede Anwendung wird als eigenständiger systemd-Service deployed und nutzt das gemeinsame SSL-Zertifikat.

Architektur

  • Testsystem (Ports 9000-9015): Nutzt Datenbank mediathek_db01 ✅ VOLLSTÄNDIG DEPLOYED
  • Produktionssystem (Ports 9100-9115): Nutzt Datenbank mediathek_db01_prod (bereit für Deployment)
  • Shared API: Zentrale Datenverwaltung für alle Tenants
  • Admin Portals: Datenverwaltung pro Tenant
  • Web Apps: Frontend für Endbenutzer pro Tenant

Mediathek

TESTSYSTEM (Ports 9000-9015)

Shared API (zentrale Datenverwaltung)

Demo Tenant

Erfal Tenant

Folgner Tenant

  • Aturis.Mediathek.Folgner.AdminPortal.csproj → Port 9008, Service: aturis-folgner-adminportal-test ✅

Klaiber Tenant

  • Aturis.Mediathek.Klaiber.AdminPortal.csproj → Port 9010, Service: aturis-klaiber-adminportal-test ✅

Windor Tenant

PRODUKTIONSSYSTEM (Ports 9100-9115) ✅ VOLLSTÄNDIG DEPLOYED

Shared API (zentrale Datenverwaltung)

  • Aturis.Mediathek.Shared.Api.csproj → Port 9115, Service: aturis-mediathek-api-prod ✅

Demo Tenant

  • Aturis.Mediathek.Demo.AdminPortal.csproj → Port 9101, Service: aturis-demo-adminportal-prod ✅
  • Aturis.Mediathek.Demo.Web.csproj → Port 9102, Service: aturis-demo-web-prod ✅

Erfal Tenant

  • Aturis.Mediathek.Erfal.AdminPortal.csproj → Port 9100, Service: aturis-erfal-adminportal-prod ✅
  • Aturis.Mediathek.Erfal.Web.csproj → Port 9106, Service: aturis-erfal-web-prod ✅

Folgner Tenant

  • Aturis.Mediathek.Folgner.AdminPortal.csproj → Port 9108, Service: aturis-folgner-adminportal-prod ✅

Klaiber Tenant

  • Aturis.Mediathek.Klaiber.AdminPortal.csproj → Port 9110, Service: aturis-klaiber-adminportal-prod ✅

Windor Tenant

  • Aturis.Mediathek.Windor.AdminPortal.csproj → Port 9112, Service: aturis-windor-adminportal-prod ✅
  • Aturis.Mediathek.Windor.Web.csproj → Port 9113, Service: aturis-windor-web-prod ✅

MESSENGER SYSTEM (Ports 9020-9025)

Das Messenger-System ist ein separates Chat-System für verschiedene Tenants. Aktuell wird der SHK Tenant im Testsystem unterstützt.

SHK Tenant (Testsystem) ✅ DEPLOYED

  • Aturis.Messenger.Api.Shk.csproj → Port 9020, Service: aturis-shk-messenger-api-test ✅
  • Aturis.Messenger.Admin.Shk.csproj → Port 9021, Service: aturis-shk-messenger-admin-test ✅

SHK Webapp (Testsystem) ✅ DEPLOYED

WARTUNGSAPPS SYSTEM (Ports 9030-9035)

Das Wartungsapps-System ist ein Multi-Tenant-System für Wartungsverwaltung verschiedener Kunden. Die Anwendungen verwenden Blazor Server-Side Rendering mit MudBlazor-Komponenten.

MHG Tenant (Testsystem)

LBR Tenant (Testsystem)

VK Tenant (Testsystem)

  • Aturis.Wartungsapp.Tenant.VK.csproj → Port 9032, Service: aturis-wartungsapp-vk-test

Aura - Multi-Tenant AI Platform

IMPORTANT: Aura uses tenant-specific environment variables for AI API keys to support multiple tenants.

Multi-Tenant Configuration System

  • Tenant Detection: Automatically extracts tenant name from app name OR config path
    • App name pattern: TestsystemAuraMur → MUR
    • Config path pattern: applications/Aura/Prod/MUR/ → MUR
  • Environment Variables: Uses format {TENANT}_GOOGLE_API_KEY, {TENANT}_OPENAI_API_KEY, etc.
  • Variable Translation: Deploy script translates MUR_GOOGLE_API_KEY → GOOGLE_API_KEY in systemd service
  • Fallback Support: Falls back to non-prefixed variables if tenant-specific ones aren't found
  • Documentation: See applications/Aura/Prod/MUR/README.md for detailed setup
  • Code Reference: Deploy-Application.ps1:265-320 for tenant variable resolution logic

Environment Variable Flow

.env file:                    MUR_GOOGLE_API_KEY=abc123
       ↓ (Deploy script reads)
Deploy script:                Detects tenant "MUR", loads MUR_GOOGLE_API_KEY
       ↓ (Translates for service)
Systemd service:              Environment=GOOGLE_API_KEY=abc123
       ↓ (Service starts app)
.NET Application:             Reads GOOGLE_API_KEY=abc123

Key Requirements for Aura Deployment

  1. Directory Permissions: /var/www/aura/ must be owned by www-data:www-data
  2. Tenant Variables: Each tenant needs {TENANT}_GOOGLE_API_KEY, {TENANT}_OPENAI_API_KEY, {TENANT}_ANTHROPIC_API_KEY in .env
  3. Config Path: App config must be in applications/Aura/[Test|Prod]/{TENANT}/ structure
  4. Service Isolation: Each tenant gets private environment variables in their systemd service

MUR Tenant (Production) ✅

  • Aturis.Aura.Tenant.Mur.csproj → Port 9041, Service: aturis-aura-mur-prod
    • Deployment: .\Deploy-Application.ps1 -AppName "MUR"
    • URL: https://ki.muetze-raetzel.de/
    • Database: aura
    • Environment Variables: MUR_GOOGLE_API_KEY, MUR_OPENAI_API_KEY, MUR_ANTHROPIC_API_KEY
    • Nginx: Resilient two-file config with Let's Encrypt (auto-renewal)

DALHOFF Tenant (Production) ✅

  • Aturis.Aura.Tenant.Dalhoff.csproj → Port 9042, Service: aturis-aura-dalhoff-prod
    • Deployment: .\Deploy-Application.ps1 -AppName "DALHOFF"
    • URL: https://ki.dalhoff-bau.de/
    • Database: aura_dalhoff
    • Environment Variables: DALHOFF_GOOGLE_API_KEY, DALHOFF_OPENAI_API_KEY, DALHOFF_ANTHROPIC_API_KEY
    • Nginx: Resilient two-file config with Let's Encrypt (auto-renewal)

DEMO Tenant (Production)

  • Aturis.Aura.Tenant.Demo.csproj → Port 9043, Service: aturis-aura-demo-prod ✅
    • Deployment: .\Deploy-Application.ps1 -AppName "DEMO"
    • URL: https://demo.kilv.de/
    • Database: aura_demo
    • Environment Variables: DEMO_GOOGLE_API_KEY, DEMO_OPENAI_API_KEY, DEMO_ANTHROPIC_API_KEY

GBN Tenant (Production) ✅

  • Aturis.Aura.Tenant.Gbn.csproj → Port 9044, Service: aturis-aura-gbn-prod
    • Deployment: .\Deploy-Application.ps1 -AppName "GBN"
    • URL: https://gbn.kilv.de/
    • Database: aura_gbn
    • Environment Variables: GBN_GOOGLE_API_KEY, GBN_OPENAI_API_KEY, GBN_ANTHROPIC_API_KEY
    • Nginx: Resilient two-file config with Let's Encrypt (auto-renewal)

WIA Tenant (Production) ✅

  • Aturis.Aura.Tenant.Wia.csproj → Port 9045, Service: aturis-aura-wia-prod
    • Deployment: .\Deploy-Application.ps1 -AppName "WIA"
    • URL: https://wia.kilv.de/
    • Database: aura_wia
    • Environment Variables: WIA_GOOGLE_API_KEY, WIA_OPENAI_API_KEY, WIA_ANTHROPIC_API_KEY
    • Nginx: Resilient two-file config with Let's Encrypt (auto-renewal)

ATURIS Tenant (Production) ✅

  • Aturis.Aura.Tenant.Aturis.csproj → Port 9046, Service: aturis-aura-aturis-prod
    • Deployment: .\Deploy-Application.ps1 -AppName "ATURIS"
    • URL: https://aura.aturis.com/
    • Database: aura_aturis
    • Environment Variables: ATURIS_GOOGLE_API_KEY, ATURIS_OPENAI_API_KEY, ATURIS_ANTHROPIC_API_KEY
    • Nginx: Resilient two-file config with Let's Encrypt (auto-renewal)

SUPERTENANT Tenant (Production) ✅

  • Aturis.Aura.Tenant.SuperTenant.csproj → Port 9047, Service: aturis-aura-supertenant-prod
    • Deployment: .\Deploy-Application.ps1 -AppName "SUPERTENANT"
    • URL: https://aurademo.aturis.com/
    • Database: aura_supertenant
    • Environment Variables: SUPERTENANT_GOOGLE_API_KEY, SUPERTENANT_OPENAI_API_KEY, SUPERTENANT_ANTHROPIC_API_KEY
    • Nginx: Resilient two-file config with Let's Encrypt (auto-renewal)

LANOPROJEKT Tenant (Production) ✅

  • Aturis.Aura.Tenant.LanoProjekt.csproj → Port 9048, Service: aturis-aura-lanoprojekt-prod
    • Deployment: .\Deploy-Application.ps1 -AppName "LANOPROJEKT"
    • URL: https://lano-projekt.kilv.de/
    • Database: aura_lanoprojekt
    • Environment Variables: LANOPROJEKT_GOOGLE_API_KEY, LANOPROJEKT_OPENAI_API_KEY, LANOPROJEKT_ANTHROPIC_API_KEY
    • Nginx: Resilient two-file config with Let's Encrypt (auto-renewal)

Adding New Aura Tenants

To add a new tenant (e.g., "ABC"):

  1. Create directory: applications/Aura/Prod/ABC/ (or Test for test systems)
  2. Copy MUR's app-config.json, update service name/port
  3. Add to .env: ABC_GOOGLE_API_KEY=..., ABC_OPENAI_API_KEY=..., ABC_ANTHROPIC_API_KEY=...
  4. Deploy: .\Deploy-Application.ps1 -AppName "ProdAuraABC" (or TestsystemAuraABC for test)

Insgesamt: 32 Anwendungen (18 Mediathek deployed ✅, 3 Messenger deployed ✅, 3 Wartungsapps bereit für Deployment, 8 Aura deployed ✅)

Überblick 📋

Dieses System bietet:

  • Einheitliches Deployment-Script gesteuert durch JSON-Konfiguration ⚙️
  • Gemeinsame SSL-Zertifikatsverwaltung 🔒
  • Automatisiertes Build und Packaging 📦
  • Systemd Service-Erstellung und -Verwaltung 🛠️
  • Datenbank-Setup und Migrationsskripte 🗄️
  • Remote-Server-Diagnose und -Monitoring 📊

Quick Start 🏃‍♂️

  1. Environment Setup

    # Kopiere und konfiguriere die Environment-Datei
    cp env.template .env
    # Bearbeite .env mit deinen Server-Details
    
  2. Anwendung deployen

    .\Deploy-Application.ps1 -AppName "TestsystemErfalAdminPortal"
    
  3. Status checken

    .\Get-ServerInfo.ps1
    
  4. Plesk zu Linode Weiterleitung in Plesk:

    • vServer → Applikation → Hosting → nginx config → zusätzliche Einstellungen (z.B. app-config.json von ProdDemoWeb)
    • Portnummer auslesen
    • Weiterleitung muss zu diesem Port gehen

Tricks und Tipps 💡

Dateien

Hin und her schieben mit WinSCP Übertragungsprotokoll → SFTP Ordner: /var/www/

Für Mediathek:

  • mediathek prod = media prod
  • mediathek test = shk
  • mediathek = media test

was verbraucht Strom:

  • htop -> Taskmanager
  • F10 zum Beenden

logs lesen einer Applikation:

  • JSON-Datei in Linode-Repo finden, z.B. app-config.json von ProdDemoWeb
  • Service-Name rauslesen: z.B. aturis-demo-web-prod
  • Dann auf SSH: journalctl -u aturis-demo-web-prod

System-Architektur 🏗️

Core Components

  • LinodeUtils.psm1: PowerShell-Modul mit gemeinsamen Deployment-Funktionen 🧩
  • Deploy-Application.ps1: Einheitliches Deployment-Script 📝
  • applications/Mediathek/: Organisierte Anwendungskonfigurationen (Test/Prod) 📁
  • build/: Konsolidiertes Build-Artefakte-Verzeichnis 🏭

Anwendungsstruktur

Jede Anwendung in applications/Mediathek/Test/ oder applications/Mediathek/Prod/ enthält:

  • app-config.json: Deployment-Konfiguration ⚙️
  • config.json: Runtime-Anwendungskonfiguration 🔧
  • README.md: Anwendungsspezifische Dokumentation 📚
  • Datenbankskripte (falls zutreffend) 🗃️

Konfiguration ⚙️

Environment-Variablen (.env)

# Server-Verbindung
LinodeIP=deine.server.ip
LinodeRootUser=root
LinodeRootPassword=dein_passwort

# SSL-Zertifikat
AspNetCorePfxPassword=dein_pfx_passwort

# Anwendungsspezifische Datenbank-Credentials
ErfalAdminTestDbUser=db_user
ErfalAdminTestDbPassword=db_password

Anwendungskonfiguration (app-config.json)

{
  "AppName": "Deine.Anwendung.Name",
  "Build": {
    "RepoUrl": "https://gitlab.com/dein/repo.git",
    "LocalRepoPath": "AturisApplications/repo",
    "ProjectPath": "pfad/zu/Project.csproj",
    "Runtime": "linux-x64"
  },
  "Database": {
    "Name": "datenbank_name",
    "UserEnvVar": "DB_USER_ENV_VAR",
    "PasswordEnvVar": "DB_PASS_ENV_VAR"
  },
     "Deployment": {
     "TargetServer": "aturis-app-1",
     "UseSharedCertificate": true,
     "RemoteBaseDir": "/var/www/deine-app",
     "RemoteAppDirName": "AppVerzeichnis",
     "RemoteAppPath": "/var/www/deine-app/AppVerzeichnis",
     "RemotePublishDir": "/var/www/deine-app/AppVerzeichnis/publish"
   },
   "Service": {
     "Name": "dein-service",
     "Port": 9000,
     "User": "www-data",
     "DllName": "Deine.App.dll",
     "UseJemalloc": false
   }
}

Service.UseJemalloc aktiviert für dynamische .NET-Dienste den installierten jemalloc-Allocator. Das Deployment bricht vor einer Serviceänderung ab, wenn das Debian-Paket libjemalloc2 auf dem Zielserver fehlt. Standardwert ist false.

Deployment-Prozess 🔄

Schritt-für-Schritt Deployment

  1. Source Control: Git-Repository klonen/updaten 📥
  2. Build: .NET-Anwendung für Linux kompilieren 🔨
  3. Package: Deployment-ZIP-Datei erstellen 📦
  4. Zertifikat: Gemeinsames SSL-Zertifikat deployen (falls konfiguriert) 🔐
  5. Upload: Anwendung auf Server übertragen ⬆️
  6. Service: Systemd-Service erstellen/updaten 🔧
  7. Cleanup: Build-Artefakte entfernen 🧹

Deployment-Optionen

# Standard-Deployment
.\Deploy-Application.ps1 -AppName "DeineApp"

SSL-Zertifikatsverwaltung 🔒

Gemeinsames Zertifikatssystem

Das System verwendet EIN gemeinsames SSL-Zertifikat für ALLE Anwendungen:

  • /etc/ssl/private/aspnetcore.pfx - Das eine PFX-Zertifikat für alle .NET Apps 🎫

Zertifikatserstellung

Das Zertifikat wird mit dem Create-Or-Update-Certificate.ps1 Script erstellt:

openssl req -x509 -newkey rsa:2048 -nodes -keyout aspnetcore.key -out aspnetcore.crt -subj "/CN=localhost" -days 365
openssl pkcs12 -export -out aspnetcore.pfx -inkey aspnetcore.key -in aspnetcore.crt -password pass:$pfxPass

Nginx Reverse Proxy & Let's Encrypt 🔄🔐

Das Deployment-System unterstützt nginx als Reverse Proxy mit Let's Encrypt SSL-Zertifikaten und automatischer Zertifikatserneuerung ohne manuelle Eingriffe.

Was ist neu?

  • Professionelle SSL-Zertifikate - Let's Encrypt pro Domain statt shared self-signed cert
  • Domain-basiertes Routing - Apps über eigene Domains erreichbar (z.B. ki.dalhoff-bau.de)
  • Sharded Konfiguration - Jede App hat eigene nginx-Config (Fehler isoliert)
  • Resiliente Zwei-Datei-Architektur - NEUE FEATURE: Garantierte ACME-Challenge-Verfügbarkeit
  • Zero-Intervention Renewals - Zertifikate erneuern sich automatisch, auch wenn sie ablaufen

Architektur

Alt (ohne nginx):

Internet → App:9042 (HTTPS via Kestrel, shared cert)

Neu (mit nginx - Resilient Two-File Approach):

Internet → nginx:80 (HTTP-only config, ACME challenges) → HTTPS redirect
Internet → nginx:443 (HTTPS-only config, Let's Encrypt) → App:9042 (HTTP localhost)

⚡ Resiliente Zwei-Datei-Architektur

Problem: Herkömmliche nginx-Konfigurationen mit kombinierten HTTP/HTTPS-Blöcken können nicht laden, wenn SSL-Zertifikate fehlen oder abgelaufen sind. Dies führt zu einem Henne-Ei-Problem bei der Zertifikatserneuerung.

Lösung: Jede Anwendung erhält ZWEI separate nginx-Konfigurationsdateien:

1. HTTP-Only Config (Port 80)

  • Datei: /etc/nginx/sites-enabled/aturis-{service-name}-http
  • KEINE SSL-Abhängigkeiten - lädt IMMER erfolgreich
  • Behandelt Let's Encrypt ACME-Challenges (/.well-known/acme-challenge/)
  • Leitet allen anderen HTTP-Traffic zu HTTPS um (301)
  • Garantiert, dass Zertifikatserneuerung funktioniert, selbst wenn Zertifikate abgelaufen sind

2. HTTPS-Only Config (Port 443)

  • Datei: /etc/nginx/sites-enabled/aturis-{service-name}-https
  • SSL/TLS-Terminierung mit Let's Encrypt-Zertifikaten
  • Reverse Proxy zur Anwendung (localhost:PORT)
  • Sicherheitsheader und WebSocket-Unterstützung
  • Wenn Zertifikate ablaufen, schlägt diese Config fehl ABER...
  • ...die HTTP-Config funktioniert weiterhin für ACME-Erneuerungen!

Vorteile:

  • ✅ Zero Manual Intervention - System heilt sich selbst, auch nach Zertifikatsablauf
  • ✅ ACME Challenges immer verfügbar - HTTP-Config hat keine SSL-Abhängigkeiten
  • ✅ Graceful Degradation - Wenn HTTPS-Config fehlschlägt, funktioniert HTTP weiterhin
  • ✅ Automatische Erneuerungen - Certbot läuft täglich um 3 Uhr morgens
  • ✅ Produktionsbereit - Bereits deployed auf MUR (ki.muetze-raetzel.de) und DALHOFF (ki.dalhoff-bau.de)

Quick Start

  1. DNS konfigurieren:

    • A-Record für Ihre Domain auf Linode-Server-IP setzen
    • Beispiel: ki.customer.com → 172.236.219.21
  2. Nginx-Sektion zu app-config.json hinzufügen:

    "Nginx": {
      "UseNginx": true,
      "DomainName": "ki.customer.com",
      "LetsEncryptEnabled": true,
      "AllowHttp": false,
      "ListenLocalOnly": true
    }
    
  3. Deployen - DAS WAR'S! 🎉

    .\Deploy-Application.ps1 -AppName "AppName"
    

Das Deployment-Script macht automatisch:

  • ✅ Nginx-Infrastruktur initialisieren (falls benötigt)
  • ✅ HTTP-only Config deployen (für ACME-Challenges)
  • ✅ Let's Encrypt-Zertifikat via HTTP-01 Challenge erwerben
  • ✅ HTTPS-only Config deployen (SSL/TLS aktivieren)
  • ✅ Automatische Erneuerung konfigurieren (täglich 3 Uhr)

Keine manuellen Schritte erforderlich! Die resiliente Zwei-Datei-Architektur garantiert, dass Zertifikate sich automatisch erneuern, selbst wenn sie ablaufen.

Konfigurationsoptionen

  • UseNginx: true = nginx Reverse Proxy, false = direktes HTTPS (legacy)
  • DomainName: Domain/Subdomain für die App (z.B. "app.customer.com")
  • LetsEncryptEnabled: true = Let's Encrypt Zertifikat, false = kein SSL in nginx
  • AllowHttp: false = HTTP→HTTPS redirect (empfohlen), true = HTTP erlaubt

Sharded Configs

Jede App erhält eigene nginx-Konfiguration:

/etc/nginx/sites-available/aturis-{service-name}
/etc/nginx/sites-enabled/aturis-{service-name} → symlink

Vorteil: Fehler in App A brechen nicht App B, C, D.

Systemd Integration

Apps mit nginx haben automatische Abhängigkeiten:

  • After=nginx.service - App startet nach nginx
  • Wants=nginx.service - App startet nginx mit falls gestoppt
  • Bei Server-Reboot: nginx → Apps automatisch gestartet

RSA 4096 Zertifikate (FortiGate-Kompatibilität)

Seit Februar 2026 verwenden alle Let's Encrypt-Zertifikate RSA 4096-Bit Schlüssel statt ECDSA. Hintergrund: Certbot 2.x erzeugt standardmäßig ECDSA-Zertifikate. Bei mindestens zwei Kunden haben Fortinet/FortiGate-Firewalls die SSL Deep Inspection dieser ECDSA-Zertifikate nicht korrekt durchführen können, wodurch unsere Webanwendungen blockiert wurden.

Resultierende Zertifikatskette (reine RSA):

Leaf-Zertifikat (RSA 4096) → R10/R11 Intermediate (RSA) → ISRG Root X1 (RSA)

Bestehende Zertifikate reparieren:

# Vorschau:
.\Repair-NginxConfigs.ps1 -DryRun

# Alle Zertifikate auf RSA 4096 umstellen + nginx-Configs aktualisieren:
.\Repair-NginxConfigs.ps1

# Einzelne App reparieren:
.\Repair-NginxConfigs.ps1 -AppName "DEMO"

Weitere Details: nginx.md - RSA 4096 Zertifikate

Default HTTPS Server (Zertifikat-Leak-Schutz)

server.aturis.com dient als neutraler Default-HTTPS-Server. Ohne diesen würde nginx bei Anfragen ohne SNI (z.B. Port-Scanner) das Zertifikat einer anderen gehosteten Anwendung offenlegen. Der Default-Server zeigt stattdessen nur server.aturis.com -- eine leere, neutrale Seite.

Eingerichtet durch Initialize-Nginx.ps1 oder Repair-NginxConfigs.ps1. Weitere Details: nginx.md - Default HTTPS Server

Weitere Informationen

📖 Detaillierte Dokumentation: nginx.md

Enthält:

  • Schritt-für-Schritt Let's Encrypt Setup
  • Nginx Konfigurationsdetails
  • Migration Guide für bestehende Apps
  • Troubleshooting und Diagnostics
  • Alle nginx/certbot Befehle

Datenbankverwaltung 🗄️

Datenbank-Setup-Skripte

Anwendungen können Datenbankskripte enthalten:

  • Initialize-Database.ps1: Datenbankstruktur erstellen 🏗️
  • Import-Database.ps1: Test-/Produktionsdaten importieren 📊

Datenbankkonfiguration

Datenbankverbindungen werden über Environment-Variablen konfiguriert und während des Deployments in die Anwendungskonfiguration injiziert.

Service-Verwaltung 🛠️

Systemd Services

Anwendungen laufen als systemd-Services mit:

  • Automatischer Neustart bei Fehlern 🔄
  • Ordnungsgemäße Benutzerberechtigungen (www-data) 👤
  • Environment-Variable-Konfiguration 🌍
  • Logging ins systemd-Journal 📝

Service-Befehle

# Service-Status prüfen
systemctl status dein-service.service

# Logs anzeigen
journalctl -u dein-service.service -f

# Service neustarten
systemctl restart dein-service.service

Administrative Skripte 🔧

Core-Skripte

  • Deploy-Application.ps1: Haupt-Deployment-Skript 🚀
  • Get-ServerInfo.ps1: Server-Status und -Diagnose 📊
  • ExecuteRemoteCommand.ps1: Befehle auf Server ausführen 💻
  • serverstatus.sh: Server-Gesundheitsprüfung 🏥
  • Create-Or-Update-Certificate.ps1: Erstellt das gemeinsame aspnetcore.pfx Zertifikat 🔐

Diagnose-Tools

# Umfassende Server-Informationen abrufen
.\Get-ServerInfo.ps1

# Benutzerdefinierten Befehl ausführen
.\ExecuteRemoteCommand.ps1 -Command "systemctl status"

# Server-Status prüfen
.\ExecuteRemoteCommand.ps1 -Command "bash serverstatus.sh"

Neue Anwendungen hinzufügen ➕

Schritt 1: Anwendungsverzeichnis erstellen

mkdir applications/Mediathek/Test/DeineNeueApp
# oder für Produktion:
mkdir applications/Mediathek/Prod/DeineNeueApp

Schritt 2: Konfiguration erstellen

Erstelle applications/Mediathek/Test/DeineNeueApp/app-config.json mit deinen Anwendungseinstellungen.

Schritt 3: Environment-Variablen hinzufügen

Füge erforderliche Datenbank-Credentials zur .env-Datei hinzu.

Schritt 4: Dokumentation erstellen

Erstelle applications/Mediathek/Test/DeineNeueApp/README.md mit anwendungsspezifischen Anweisungen.

Schritt 5: Deployen

.\Deploy-Application.ps1 -AppName "DeineNeueApp"

Server Provisioning for Horizontal Scaling

This section documents the complete process for provisioning new, identical Linode servers. Follow these steps whenever adding a new application server.

Current Infrastructure

Server Public IP VPC IP OS Role
aturis-app-1 172.236.219.21 10.0.0.2 Debian 12 Connectivity server: nginx, Let's Encrypt/certbot, MariaDB, Redis, Docker, and legacy/local apps
aturis-app-2 172.236.203.80 10.0.0.3 Debian 13 Application server: Aura apps behind app-1 nginx via VPC
aturis-app-3 172.238.110.103 10.0.0.4 Debian 12 Application server: additional Aturis/Aura apps behind app-1 nginx via VPC
aturis-app-4 172.236.219.51 10.0.0.5 Debian 13 Application server
aturis-app-5 172.236.212.9 10.0.0.6 Debian 12 Application server, including Lano
aturis-app-6 172.238.119.167 10.0.0.7 Debian 13 Application server, provisioned

All servers connected via VPC in Frankfurt datacenter (sub-millisecond latency).

Server Roles

aturis-app-1 is the only connectivity edge for public HTTP(S) traffic. It owns nginx, Let's Encrypt/certbot state, public certificates, MariaDB, Redis, and Docker-based shared services. Public domains terminate on app-1 and are proxied over the VPC to application servers when needed.

aturis-app-2 through aturis-app-6 are application servers. They run yeetApp systemd user services and listen only on the application ports assigned by deployed apps. They do not need nginx, certbot, Redis, Docker, or git for normal deployments. Having no open application ports on a fresh app server is expected until the first app is deployed.

Certificates are stored and renewed on aturis-app-1. Cross-server apps still use Nginx.UseNginx=true, but nginx config and certbot operations happen on app-1 while the app process runs on its TargetServer.

Traffic Monitoring on aturis-app-1

aturis-app-1 runs ntopng for graphical traffic visibility and GeoIP/ASN resolution.

Component Location Notes
ntopng Docker container ntopng (ntop/ntopng:latest) Captures eth0 and eth1, uses libpcap fallback if PF_RING is not loaded
ntopng Redis Docker container ntopng-redis (redis:7-alpine) Bound to 127.0.0.1:6380, data in /opt/ntopng/redis-data
ntopng data /opt/ntopng/ntopng Persistent ntopng state
Web UI backend 127.0.0.1:3001 Local-only; do not expose this port directly
Public URL https://ntopng.aturis.net nginx reverse proxy with Let's Encrypt certificate
nginx config /etc/nginx/sites-available/aturis-ntopng-http and aturis-ntopng-https Symlinked in sites-enabled
Access restriction nginx allowlist ATURIS external IPs only (87.138.204.149, 212.72.184.100) plus localhost

Operational checks:

.\ExecuteRemoteCommand.ps1 -Server aturis-app-1 -Command "docker ps --filter name=ntopng"
.\ExecuteRemoteCommand.ps1 -Server aturis-app-1 -Command "curl -k -I --resolve ntopng.aturis.net:443:127.0.0.1 https://ntopng.aturis.net/"
.\ExecuteRemoteCommand.ps1 -Server aturis-app-1 -Command "tail -50 /var/log/nginx/ntopng-error.log"

Important: ntopng must use its dedicated Redis on 127.0.0.1:6380. Do not let it fall back to the shared Redis on 127.0.0.1:6379.

The container entrypoint waits for PONG from 127.0.0.1:6380, then executes /usr/bin/ntopng directly with the configured arguments. Do not call the image's /run.sh: it starts an additional Redis on host port 6379 and prevents AURA Redis from publishing that port. Preserve the direct entrypoint when recreating or upgrading the container. The replacement on 2026-09-08 retains the pinned image, mounts, capabilities, logging limits and unless-stopped policy; previous containers have restart disabled.

Repeatable AURA host setup

The authoritative runbook is docs/prepare-new-server.md.

Shared Office/PDF converter updates on app-1: Gotenberg runbook. The package list lives only in scripts/ensure-aura-runtime.sh. It provides .NET9+10 SDKs/runtimes,document/media tools,fonts,Node/npm,Python and deployment utilities. Office dependencies and their sandbox test come from the intended AturisSoftware revision. Debian12/13 retain their distribution-supported package versions; parity means capability,not identical version strings.

# Fresh host after VPC/firewall/.env/host-key preparation:
./Initialize-AuraHost.ps1 -Server aturis-app-6 -Mode NewHost -OfficePrerequisitesPath C:/Repos/messenger/Aura/Scripts/OfficeSandbox/install-prerequisites.sh
# Existing host: dependencies only; no automatic app restart or reboot:
./Initialize-AuraHost.ps1 -Server aturis-app-3 -Mode Dependencies -OfficePrerequisitesPath C:/Repos/messenger/Aura/Scripts/OfficeSandbox/install-prerequisites.sh
# Read-only acceptance:
./Initialize-AuraHost.ps1 -Server aturis-app-6 -Mode Verify

For existing hosts,roll out one host at a time and compare service PIDs/restarts and HTTP health before/after. The runbook covers VPC activation/reboot,4GiB swap verification,team/CI SSH keys,shared credentials, maintenance,backup checks and per-application DB grants. New host provisioning does not move customers. Do not install nginx,certbot,MariaDB server,Redis server or Docker on application hosts for the shared topology.

Deploying Apps to the New Server

  1. Set TargetServer in the app's app-config.json:

    "Deployment": {
      "TargetServer": "<server-name>"
    }
    
  2. Deploy: pwsh -NoProfile -Command ".\Deploy-Application.ps1 -AppName '<FolderName>'"

The deployment script handles cross-server nginx proxy configuration, VPC IPs in connection strings, and SSL certificates automatically.

For cross-server deployments, nginx and certbot stay on aturis-app-1. The target app server only needs the app runtime, deployment users, /var/www permissions, VPC connectivity, and the shared credential files required by that app.

Cross-Server Deployment Details

For edge cases and troubleshooting cross-server deployments, see docs/prepare-new-server.md:

  • SSL mode for Debian 13 MariaDB clients
  • Connection strings pointing to VPC IP
  • SSH host key acceptance
  • Nginx reverse proxy to apps on other servers via VPC

Troubleshooting 🔍

Häufige Probleme

  1. Build-Fehler: .NET SDK-Version und Projektabhängigkeiten prüfen ⚠️
  2. Berechtigungsfehler: Prüfen, ob www-data-Benutzer ordnungsgemäße Berechtigungen hat 🚫
  3. Zertifikatsprobleme: PFX-Passwort und Dateiberechtigungen prüfen 🔐
  4. Service-Start: Systemd-Logs für detaillierte Fehlermeldungen überprüfen 📋

Aura-Spezifische Probleme

  1. "Required configuration value 'GOOGLE_API_KEY' not found":

    • Überprüfen Sie, dass {TENANT}_GOOGLE_API_KEY in der .env-Datei vorhanden ist
    • Stellen Sie sicher, dass /var/www/aura/ die richtigen Berechtigungen hat (www-data:www-data)
    • Führen Sie das Deployment erneut aus, um die Environment-Variablen zu aktualisieren
  2. File Upload Fehler bei Aura-Deployments:

    • Problem: /var/www/aura/ ist oft standardmäßig im Besitz von root:root
    • Lösung: chown -R www-data:www-data /var/www/aura/
  3. Tenant-Detection schlägt fehl:

    • Deploy-Script erkennt Aura-Apps über AppName (*Aura*) oder Config-Pfad (*Aura*)
    • Debug-Output: "Detected Aura tenant: {TENANT}" muss in den Logs erscheinen

Debug-Befehle

# Build-Artefakte prüfen
ls build/

# Service-Logs anzeigen
.\ExecuteRemoteCommand.ps1 -Command "journalctl -u dein-service.service --no-pager"

# Zertifikatsberechtigungen prüfen
.\ExecuteRemoteCommand.ps1 -Command "ls -la /etc/ssl/pfx/"

# Service-Konfiguration verifizieren
.\ExecuteRemoteCommand.ps1 -Command "systemctl show dein-service.service"

Sicherheitsüberlegungen 🛡️

  • Sensitive Credentials in .env-Datei speichern (nicht in Versionskontrolle) 🔒
  • Starke PFX-Passwörter für SSL-Zertifikate verwenden 💪
  • SSH-Zugang nur auf autorisierte Benutzer beschränken 🚪
  • Regelmäßig Server-Pakete und Sicherheits-Patches aktualisieren 🔄
  • Service-Logs auf verdächtige Aktivitäten überwachen 👀

CAA-Policy für projektbezogene HTTPS-Endpunkte

CAA wird ausschließlich am projektspezifischen FQDN gesetzt, den ATURIS für den jeweiligen AURA-Endpunkt kontrolliert. Keine Policy ungeprüft auf einer Kunden-Zone oder deren Apex setzen. Bei Zertifikaten mit AlternateDomains muss jeder einzelne SAN-Name dieselbe kompatible Policy liefern.

Zielpolicy der ersten Stufe:

TTL 300
CAA 0 issue "letsencrypt.org; validationmethods=http-01"
  • TTL 300 Sekunden verwenden; falls der DNS-Provider dies nicht unterstützt, maximal 3600 Sekunden.
  • Kein Critical-Flag 128 verwenden.
  • Zunächst keine accounturi binden. Produktion und Let's-Encrypt-Staging verwenden getrennte ACME-Accounts; eine vorschnelle Bindung blockiert certbot renew --dry-run.
  • Änderungen nur montags bis donnerstags zwischen 08:00 und 09:00 Uhr durchführen.
  • Nur ändern, wenn alle betroffenen Zertifikate mindestens 30 Tage Restlaufzeit besitzen.
  • Vorher und nachher jeden DomainName und jede AlternateDomain gegen autoritative DNS-Server sowie zwei öffentliche Resolver prüfen.
  • Danach certbot renew --dry-run, nginx-Konfiguration, SANs, Zertifikatskette und HTTPS-Erreichbarkeit prüfen.
  • CAA macht vorhandene Zertifikate nicht ungültig. Bei einer Fehlkonfiguration den CAA-Record am konkreten FQDN entfernen oder vorübergehend auf CAA 0 issue "letsencrypt.org" lockern.
  • Trotz niedriger DNS-TTL bei einer Korrektur mit bis zu acht Stunden CA-seitiger Wiederverwendung einer früheren CAA-Prüfung rechnen.

Rollout-Reihenfolge:

  1. test.aura.aturis.com als Single-SAN-Canary.
  2. Weitere von ATURIS kontrollierte Single-SAN-Testendpunkte.
  3. Single-SAN-Produktivendpunkte.
  4. Multi-SAN-Zertifikate erst nach erfolgreichem Nachweis für jeden beteiligten Namen.
  5. Der Deploy-Preflight bleibt während des Rollouts bei CAA-Abweichungen warnend. Erst nach vollständiger DNS-Abdeckung darf er in einem separaten Commit fail-closed geschaltet werden.

Eine spätere accounturi-Bindung benötigt vorab einen nachgewiesenen Export und eine getestete Wiederherstellung der Produktions- und Staging-Account-Keys sowie einen unabhängig erreichbaren DNS-Break-Glass-Zugang. Produktions- und Staging-Account werden dann als zwei additive CAA-Records zugelassen, damit der Dry-Run erhalten bleibt.

Anforderungen 📋

Lokale Entwicklungsmaschine

  • PowerShell7 (pwsh) für die aktuellen Provisionierungsbefehle 💻
  • .NET SDK 10 für aktuelle AURA-Builds; SDK9 für ältere Anwendungen 🔧
  • Git-Client 📥
  • PuTTY-Tools (plink.exe, pscp.exe) im PATH 🛠️

Linode Server

  • Debian12/13 🐧
  • .NET9+10 SDKs/Runtimes und AURA-Abhängigkeiten gemäß Initialize-AuraHost.ps1 ⚙️
  • MariaDB-Client auf Apphosts; zentraler Datenbankserver auf app-1 🗄️
  • OpenSSL für Zertifikatsgenerierung 🔐
  • Systemd für Service-Verwaltung 🛠️

Setup Dependencies

Run \Install-Dependencies.ps1 to install/check:

  • Posh-SSH module
  • Git (via winget if avail, else warn)
  • PuTTY (plink/pscp via winget if avail, else warn)

Assumes .NET SDK installed.

Lizenz 📄

Dieses Deployment-System ist proprietäre Software für Aturis-Anwendungen.