Gongomat Dokumentation
Azure Deployment Anleitung - Gongomat Testsystem
Übersicht
Diese Anleitung beschreibt das Deployment der Gongomat Blazor Server-Anwendung auf ein Azure-Testsystem.
TODO: Beschreibung Übernahme GongomatUhr Projekt
Projektbeschreibung
- Typ: Blazor Server (.NET 8)
- Framework: ASP.NET Core 8.0
- Authentifizierung: ASP.NET Core Identity mit Rollen
- Datenbanken: 2 SQL Server-Datenbanken (Identity + Gongomat)
- Features: SignalR (ClientHub), Web APIs, QR-Code-Generierung, Lokalisierung (de-CH, en-US)
Benötigte Azure-Ressourcen
1. Azure App Service
- Service Plan: B1 oder höher (Basic oder Standard empfohlen für Testsystem)
- Runtime Stack: .NET 8 (LTS)
- Operating System: Linux oder Windows
- Region: West Europe (für EU-Daten) oder nach Bedarf
2. Azure SQL Database
Zwei Datenbanken werden benötigt:
- ApplicationDB: Für ASP.NET Core Identity (Benutzer, Rollen)
- GongomatDB: Für Anwendungsdaten (Clients, Gongs, Patterns, Exams)
Empfohlene Konfiguration für Testsystem:
- Service Tier: Basic oder S0 (Standard)
- Compute Tier: Serverless (kosteneffizient für Tests)
- Backup: Geo-redundant für Production, lokal-redundant für Test
Deployment-Schritte
Schritt 1: Azure-Ressourcen erstellen
Option A: Über Azure Portal
Resource Group erstellen
- Portal → Resource Groups → Create
- Name:
rg-gongomat-test - Region: West Europe
SQL Server erstellen
- Portal → SQL servers → Create
- Server Name:
sql-gongomat-test(muss global eindeutig sein) - Authentication: SQL authentication + Azure AD authentication (empfohlen)
- Firewall: "Allow Azure services and resources to access this server" aktivieren
Datenbanken erstellen
- Zwei Datenbanken auf dem erstellten SQL Server:
db-gongomat-identity-testdb-gongomat-data-test
- Zwei Datenbanken auf dem erstellten SQL Server:
App Service Plan erstellen
- Portal → App Service Plans → Create
- Name:
asp-gongomat-test - OS: Linux (günstiger) oder Windows
- Pricing Tier: B1 oder S1
App Service (Web App) erstellen
- Portal → App Services → Create → Web App
- Name:
app-gongomat-test(wird zu app-gongomat-test.azurewebsites.net) - Runtime stack: .NET 8 (LTS)
- Operating System: Linux oder Windows (muss zum App Service Plan passen)
- App Service Plan:
asp-gongomat-test(vorher erstellt)
Option B: Über Azure CLI
# Login
az login
# Resource Group erstellen
az group create --name rg-gongomat-test --location westeurope
# SQL Server erstellen
az sql server create \
--name sql-gongomat-test \
--resource-group rg-gongomat-test \
--location westeurope \
--admin-user gongomat-admin \
--admin-password "IhrSicheresPasswort123!"
# Firewall-Regel für Azure Services
az sql server firewall-rule create \
--resource-group rg-gongomat-test \
--server sql-gongomat-test \
--name AllowAzureServices \
--start-ip-address 0.0.0.0 \
--end-ip-address 0.0.0.0
# Datenbanken erstellen
az sql db create \
--resource-group rg-gongomat-test \
--server sql-gongomat-test \
--name db-gongomat-identity-test \
--service-objective S0
az sql db create \
--resource-group rg-gongomat-test \
--server sql-gongomat-test \
--name db-gongomat-data-test \
--service-objective S0
# App Service Plan erstellen
az appservice plan create \
--name asp-gongomat-test \
--resource-group rg-gongomat-test \
--sku B1 \
--is-linux
# Web App erstellen
az webapp create \
--resource-group rg-gongomat-test \
--plan asp-gongomat-test \
--name app-gongomat-test \
--runtime "DOTNETCORE:8.0"
Schritt 2: Connection Strings konfigurieren
Im Azure Portal:
- App Service öffnen → Configuration → Connection strings
- Zwei Connection Strings hinzufügen:
DefaultConnection (Type: SQLAzure):
Server=tcp:sql-gongomat-test.database.windows.net,1433;Initial Catalog=db-gongomat-identity-test;Persist Security Info=False;User ID=gongomat-admin;Password=IhrSicheresPasswort123!;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
GongomatConnection (Type: SQLAzure):
Server=tcp:sql-gongomat-test.database.windows.net,1433;Initial Catalog=db-gongomat-data-test;Persist Security Info=False;User ID=gongomat-admin;Password=IhrSicheresPasswort123!;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
Über Azure CLI:
az webapp config connection-string set \
--resource-group rg-gongomat-test \
--name app-gongomat-test \
--connection-string-type SQLAzure \
--settings DefaultConnection="Server=tcp:sql-gongomat-test.database.windows.net,1433;Initial Catalog=db-gongomat-identity-test;Persist Security Info=False;User ID=gongomat-admin;Password=IhrSicheresPasswort123!;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" \
GongomatConnection="Server=tcp:sql-gongomat-test.database.windows.net,1433;Initial Catalog=db-gongomat-data-test;Persist Security Info=False;User ID=gongomat-admin;Password=IhrSicheresPasswort123!;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
Schritt 3: Application Settings konfigurieren
Im Azure Portal → App Service → Configuration → Application settings:
ASPNETCORE_ENVIRONMENT = Staging (oder Production)
WEBSITE_TIME_ZONE = W. Europe Standard Time
Wichtig für SignalR:
WEBSITE_ENABLE_SYNC_UPDATE_SITE = true
WEBSITE_ADD_SITENAME_BINDINGS_IN_APPHOST_CONFIG = 1
Für WebSocket-Support (SignalR):
Im Azure Portal → Configuration → General settings:
- Web sockets: On
Schritt 4: Anwendung vorbereiten
4.1 appsettings.Production.json erstellen
Erstellen Sie eine neue Datei im Projekt:
{
"ConnectionStrings": {
"DefaultConnection": "",
"GongomatConnection": ""
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning"
}
},
"AllowedHosts": "*"
}
4.2 Anwendung veröffentlichen
Option A: Visual Studio
- Rechtsklick auf Projekt → Publish
- Target: Azure → Azure App Service (Linux/Windows)
- Subscription auswählen
- App Service auswählen:
app-gongomat-test - Publish klicken
Option B: Visual Studio Code / CLI
# Im Projektverzeichnis
dotnet publish -c Release -o ./publish
# ZIP erstellen
cd publish
Compress-Archive -Path * -DestinationPath ../gongomat.zip
# Mit Azure CLI deployen
az webapp deployment source config-zip \
--resource-group rg-gongomat-test \
--name app-gongomat-test \
--src gongomat.zip
Option C: GitHub Actions (CI/CD)
Erstellen Sie .github/workflows/azure-deploy.yml:
name: Deploy to Azure
on:
push:
branches:
- GomgomatV2 # Ihr Branch
env:
AZURE_WEBAPP_NAME: app-gongomat-test
AZURE_WEBAPP_PACKAGE_PATH: './Gongomat'
DOTNET_VERSION: '8.0.x'
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Restore dependencies
run: dotnet restore
working-directory: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
- name: Build
run: dotnet build --configuration Release --no-restore
working-directory: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
- name: Publish
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/gongomat
working-directory: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}
- name: Deploy to Azure Web App
uses: azure/webapps-deploy@v2
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: ${{env.DOTNET_ROOT}}/gongomat
Schritt 5: Datenbank-Migrationen ausführen
Option A: Über lokale Entwicklungsumgebung
Passen Sie temporär die appsettings.json an oder verwenden Sie User Secrets:
# Connection Strings setzen
dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=tcp:sql-gongomat-test.database.windows.net,1433;..."
dotnet user-secrets set "ConnectionStrings:GongomatConnection" "Server=tcp:sql-gongomat-test.database.windows.net,1433;..."
# Migrationen ausführen
dotnet ef database update --context ApplicationDbContext
dotnet ef database update --context GongomatContext
Option B: Startup-Migration (in Program.cs)
Fügen Sie vor app.Run() hinzu (nur für Test, nicht für Production empfohlen):
// Automatische Migration beim Start (nur für Testsystem)
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var identityDb = services.GetRequiredService<ApplicationDbContext>();
var gongomatDb = services.GetRequiredService<GongomatContext>();
identityDb.Database.Migrate();
gongomatDb.Database.Migrate();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred while migrating the database.");
}
}
Option C: Azure App Service SSH/Console
Im Portal → App Service → SSH/Advanced Tools (Kudu) → SSH:
cd /home/site/wwwroot
dotnet Gongomat.dll --migrate
Schritt 6: Erste Benutzer anlegen
Da die Anwendung RequireConfirmedAccount = true verwendet, müssen Sie initial einen Admin-User erstellen.
Option 1: Temporär RequireConfirmedAccount deaktivieren
- In
Program.csändern:options.SignIn.RequireConfirmedAccount = false - Deployen, registrieren, Admin-Rolle zuweisen
- Zurück auf
truesetzen
Option 2: Direkt in Datenbank
-- Verbindung zur Identity-Datenbank
-- User und Admin-Rolle erstellen
-- (Beispiel-SQL-Skripte im Anhang)
Schritt 7: Konfiguration überprüfen
App Service Logs aktivieren
Azure Portal → App Service → Monitoring → App Service Logs:
- Application Logging: File System (Information)
- Detailed Error Messages: On
- Failed Request Tracing: On
Logs ansehen
az webapp log tail --name app-gongomat-test --resource-group rg-gongomat-test
Oder im Portal → Log Stream
Wichtige Besonderheiten für Gongomat
1. SignalR (ClientHub)
- WebSockets müssen aktiviert sein (siehe Schritt 3)
- In Azure skaliert SignalR mit Azure SignalR Service besser (optional für Test)
2. SkiaSharp (QR-Code / Grafik)
Falls SkiaSharp-Fehler auftreten:
- Bei Linux App Service:
SkiaSharp.NativeAssets.Linux.NoDependenciesist bereits im Projekt - Bei Windows: Standard SkiaSharp funktioniert
3. Kestrel IPv4 Configuration
Die Zeile serverOptions.Listen(IPAddress.Any, 5226); in Program.cs sollte für Azure entfernt oder bedingt sein:
if (builder.Environment.IsDevelopment())
{
builder.WebHost.ConfigureKestrel(serverOptions =>
{
serverOptions.Listen(IPAddress.Any, 5226);
});
}
Sicherheitsempfehlungen für Testsystem
1. SQL-Zugriff beschränken
# Nur spezifische IPs erlauben
az sql server firewall-rule create \
--resource-group rg-gongomat-test \
--server sql-gongomat-test \
--name AllowMyIP \
--start-ip-address <IhreIP> \
--end-ip-address <IhreIP>
2. Managed Identity verwenden (empfohlen)
Statt SQL-Authentication:
- System-assigned Managed Identity für App Service aktivieren
- SQL-Datenbank mit Azure AD-User für Managed Identity konfigurieren
- Connection String anpassen:
Server=...; Authentication=Active Directory Default; Database=...
3. Azure Key Vault (Optional, für Secrets)
az keyvault create \
--name kv-gongomat-test \
--resource-group rg-gongomat-test \
--location westeurope
# Secrets hinzufügen
az keyvault secret set \
--vault-name kv-gongomat-test \
--name "DefaultConnection" \
--value "Server=tcp:..."
In App Service Configuration:
@Microsoft.KeyVault(SecretUri=https://kv-gongomat-test.vault.azure.net/secrets/DefaultConnection/)
Monitoring & Troubleshooting
Application Insights (empfohlen)
- Application Insights Ressource erstellen
- Connection String in App Service Configuration:
APPLICATIONINSIGHTS_CONNECTION_STRING = <connection-string> - NuGet-Package hinzufügen:
dotnet add package Microsoft.ApplicationInsights.AspNetCore - In
Program.cs:builder.Services.AddApplicationInsightsTelemetry();
Häufige Probleme
Problem: HTTP 500 Fehler
- Lösung: Logs in Log Stream prüfen, DeveloperPageException aktivieren für mehr Details
Problem: Datenbank-Verbindungsfehler
- Firewall-Regeln prüfen
- Connection String validieren
- SQL Server erreichbar?
Test-NetConnection sql-gongomat-test.database.windows.net -Port 1433
Problem: SignalR funktioniert nicht
- WebSockets aktiviert?
- ARR Affinity für Sticky Sessions: On (bei Scale-out)
Problem: 503 Service Unavailable
- App startet nicht → Startup-Logs prüfen
- Migrations-Fehler? → Manuell ausführen
Kosten-Übersicht (Testsystem, ca.)
- App Service B1: ~13 EUR/Monat
- SQL Database S0 x2: ~30 EUR/Monat
- Application Insights: ~5 EUR/Monat (bei geringem Traffic)
- Gesamt: ~50 EUR/Monat
Spar-Tipps:
- Serverless SQL Database für Test
- App Service außerhalb der Testzeiten stoppen
- Free-Tier von Application Insights nutzen
Nützliche CLI-Befehle
# App starten/stoppen
az webapp start --name app-gongomat-test --resource-group rg-gongomat-test
az webapp stop --name app-gongomat-test --resource-group rg-gongomat-test
# Logs streamen
az webapp log tail --name app-gongomat-test --resource-group rg-gongomat-test
# App neustarten
az webapp restart --name app-gongomat-test --resource-group rg-gongomat-test
# Deployment-Status
az webapp deployment list-publishing-profiles --name app-gongomat-test --resource-group rg-gongomat-test
# App-Settings auflisten
az webapp config appsettings list --name app-gongomat-test --resource-group rg-gongomat-test
Checkliste vor Go-Live (Test)
- Azure-Ressourcen erstellt (App Service, SQL Databases)
- Connection Strings konfiguriert
- WebSockets aktiviert
- Datenbank-Migrationen ausgeführt
- Admin-Benutzer erstellt
- App erfolgreich deployed
- Logs aktiviert
- Health-Check: Anwendung erreichbar unter https://app-gongomat-test.azurewebsites.net
- SignalR-Verbindung funktioniert (ClientHub)
- Authentifizierung/Autorisierung funktioniert
- API-Endpunkte erreichbar (/api/exams, /api/sounds, /api/gongs)
- QR-Code-Generierung funktioniert
Support & Weitere Informationen
Anhang: SQL-Skripte für Initial Setup
Admin-User erstellen (in Identity DB)
-- Beispiel: Password: Admin123! (Hash muss mit ASP.NET Core Identity übereinstimmen)
-- Verwenden Sie lieber die Registrierungs-UI oder ein Setup-Skript in C#
-- Rollen erstellen
INSERT INTO AspNetRoles (Id, Name, NormalizedName, ConcurrencyStamp)
VALUES
(NEWID(), 'Admin', 'ADMIN', NEWID()),
(NEWID(), 'User', 'USER', NEWID());
-- User manuell zu erstellen ist komplex wegen Password-Hashing
-- Empfehlung: Startup-Code für Seed-Data verwenden
Besser: Startup-Seed in Program.cs:
using (var scope = app.Services.CreateScope())
{
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var roleManager = scope.ServiceProvider.GetRequiredService<RoleManager<IdentityRole>>();
// Rollen erstellen
if (!await roleManager.RoleExistsAsync("Admin"))
{
await roleManager.CreateAsync(new IdentityRole("Admin"));
}
// Admin-User erstellen
var adminEmail = "admin@gongomat.test";
var adminUser = await userManager.FindByEmailAsync(adminEmail);
if (adminUser == null)
{
adminUser = new ApplicationUser
{
UserName = adminEmail,
Email = adminEmail,
EmailConfirmed = true
};
await userManager.CreateAsync(adminUser, "Admin123!");
await userManager.AddToRoleAsync(adminUser, "Admin");
}
}
Version: 1.0
Stand: 2024
Projekt: Gongomat V2
