Zum Inhalt

Architekturübersicht

KanjiIQ folgt einer Multi-Container-Pod-Architektur, die auf Kubernetes bereitgestellt wird. Frontend und Backend laufen als separate Container innerhalb desselben Pods und kommunizieren über localhost.

Systemdiagramm

graph TB
    subgraph Internet
        U[User Browser]
    end

    subgraph Hetzner["Hetzner k3s Cluster"]
        subgraph NS["Namespace: jlpt-kanji"]
            T[Traefik Ingress Controller]

            subgraph Pod["Application Pod (x2 replicas)"]
                FE[Flutter Web<br/>Nginx :80]
                BE[Dart Frog API<br/>:8080]
            end

            PG[(PostgreSQL 15<br/>PVC)]

            subgraph Middleware["Traefik Middlewares"]
                RL[Rate Limiting]
                SH[Security Headers]
            end
        end

        CM[cert-manager<br/>Let's Encrypt]
    end

    U -->|HTTPS| T
    T --> Middleware
    Middleware -->|kanjiiq.com| FE
    Middleware -->|api.kanjiiq.com| BE
    FE -->|/api/ proxy| BE
    BE --> PG
    CM -->|TLS Certificates| T

Domain-Architektur

Domain Dienst Zweck
kanjiiq.com Frontend (Nginx) Flutter Web Anwendung
www.kanjiiq.com Frontend (Nginx) Weiterleitung zur Hauptdomain
api.kanjiiq.com Backend (Dart Frog) REST API
admin.kanjiiq.com Backend (Dart Frog) Admin-Dashboard API
docs.kanjiiq.app Docs (Nginx) Diese Dokumentationsseite

Multi-Container-Pod-Design

Die Anwendung läuft als einzelnes Kubernetes Deployment mit 2 Replikaten, die jeweils zwei Container enthalten:

# Simplified view of k8s/05-deployment.yaml
spec:
  replicas: 2
  template:
    spec:
      containers:
        - name: backend    # Dart Frog API on :8080
        - name: frontend   # Nginx serving Flutter Web on :80

Warum ein Multi-Container-Pod?

  • Das Frontend-Nginx leitet /api/-Anfragen an localhost:8080 (das Backend) weiter und vermeidet so Cross-Origin-Probleme
  • Beide Container skalieren gemeinsam — jedes Replikat ist eine vollständige, eigenständige Einheit
  • Vereinfachtes Netzwerk: Die Frontend-zu-Backend-Kommunikation bleibt innerhalb des Pods

Komponentenübersicht

Frontend

  • Framework: Flutter Web mit Material Design 3
  • Bereitstellung: Nginx Alpine (non-root, UID 1000)
  • Zustandsverwaltung: Provider
  • Routing: GoRouter
  • Offline-Unterstützung: Lokaler SQLite-Cache mit Hintergrundsynchronisation

Backend

  • Framework: Dart Frog 1.1.0
  • Authentifizierung: JWT (für Admin-Endpunkte)
  • Sicherheit: Mehrschichtiger Middleware-Stack (IP-Blockierung, Pfaderkennung, Ratenbegrenzung)
  • Übersetzung: OpenAI API für dynamische Inhaltsübersetzung

Datenbank

  • Engine: PostgreSQL 15
  • Speicher: Kubernetes PersistentVolumeClaim (10Gi)
  • Schema: JSONB-Spalten für mehrsprachige Inhaltsspeicherung
  • Primärschlüssel: UUID

Infrastruktur

  • Cluster: k3s auf Hetzner Dedicated Server
  • Ingress: Traefik mit automatischem HTTPS
  • TLS: cert-manager mit Let's Encrypt
  • CI/CD: Forgejo Actions (selbst gehostet)
  • Registry: Forgejo Container Registry

Sicherheitsschichten

KanjiIQ implementiert Tiefenverteidigung mit mehreren Sicherheitsschichten:

graph LR
    R[Request] --> L1[Traefik<br/>Rate Limiting]
    L1 --> L2[Traefik<br/>Security Headers]
    L2 --> L3[App: IP<br/>Blocklist Check]
    L3 --> L4[App: Malicious<br/>Path Detection]
    L4 --> L5[App: SQL Injection<br/>Detection]
    L5 --> L6[App: Regional<br/>Analytics]
    L6 --> H[Request Handler]
  1. Infrastrukturebene (Traefik): Ratenbegrenzung (100 Req/Min öffentlich, 50 Req/Min Admin) und Sicherheitsheader (HSTS, X-Frame-Options, CSP)
  2. Anwendungsebene (Dart Frog Middleware): IP-Blockliste, Erkennung bösartiger Pfade (.env, .php, Konfigurationsdateien), SQL-Injection-Muster, Verhinderung von Pfadtraversierung
  3. Analyseebene: Regionale Anfrageverfolgung mit automatischer Blockierung nach 3 verdächtigen Anfragen innerhalb von 24 Stunden

Siehe Backend-Architektur für Details zum Middleware-Stack.