Zum Inhalt

Backend

Diese Anleitung beschreibt, wie das ChronoScope-Backend in einer Produktivumgebung eingerichtet und gestartet wird. Das Backend ist eine Spring-Boot-Anwendung und stellt die REST-API für Aufgaben, Arbeitszeiten, Planung, Organisationen und Benutzeridentität bereit.

Kurzüberblick

Das Backend wird im Produktivbetrieb als Docker-Container gestartet. Zusätzlich werden eine SQL-Datenbank, ein SMTP-Server und eine Keycloak-Installation benötigt.

Voraussetzungen

Für den Betrieb werden folgende Komponenten benötigt:

Komponente Empfehlung Zweck
Docker Aktuelle stabile Version Startet das Backend als Container
Docker Compose Aktuelle stabile Version Verwaltet Backend und Datenbank gemeinsam
Datenbank MySQL, MariaDB oder kompatibel Speichert Aufgaben, Arbeitszeiten und Planungsdaten
Keycloak Bereits erreichbar Prüft Tokens und verwaltet Organisationen
SMTP-Server Lokal oder extern erreichbar Versendet Einladungen und Account-Link-E-Mails
Reverse Proxy Nginx, Apache oder vergleichbar Veröffentlicht die API kontrolliert nach außen
HTTPS-Zertifikat z. B. Let's Encrypt Schützt Login- und API-Kommunikation

HTTPS verwenden

Das Backend sollte in der Produktivumgebung nur über HTTPS erreichbar sein. Zugriffstokens und personenbezogene Daten dürfen nicht über unverschlüsselte Verbindungen übertragen werden.

Datenbank vorbereiten

ChronoScope benötigt eine SQL-Datenbank. Für eine einfache produktionsnahe Installation kann MySQL direkt über Docker Compose mitgestartet werden. In einer bestehenden Kundenumgebung kann stattdessen auch eine vorhandene MySQL- oder MariaDB-Instanz verwendet werden.

Für eine externe Datenbank werden folgende Informationen benötigt:

Wert Beispiel
Datenbankname chronoscope
JDBC-URL jdbc:mysql://mysql:3306/chronoscope
Benutzername chronoscope
Passwort Starkes individuelles Passwort

Datenbank nicht öffentlich freigeben

Die Datenbank muss nur vom Backend erreichbar sein. Sie sollte nicht direkt aus dem Internet erreichbar sein.

SMTP-Server vorbereiten

Das Backend verwendet SMTP, um E-Mails zu versenden. Dazu gehören zum Beispiel Einladungen oder Nachrichten zum Verknüpfen von Accounts.

Der SMTP-Server kann intern oder extern betrieben werden. Wichtig ist, dass das Backend den Host und Port erreichen kann.

Einstellung Beispiel
SMTP-Host smtp.example.org
SMTP-Port 25 oder 587

Wenn der SMTP-Server auf demselben Host wie Docker läuft, kann je nach Umgebung host.docker.internal verwendet werden.

Keycloak vorbereiten

ChronoScope nutzt Keycloak für Authentifizierung, Benutzeridentität und Organisationsverwaltung. Für das Backend wird ein vertraulicher Keycloak-Client benötigt, über den das Backend administrative Organisationsfunktionen ausführen kann.

In Keycloak sollten vorbereitet werden:

Einstellung Beschreibung
Realm Realm für ChronoScope, zum Beispiel ni0
Backend-Client Vertraulicher Client für Backend-Administrationszugriffe
Client-ID Wird als KEYCLOAK_CLIENT_ID im Backend gesetzt
Client-Secret Wird als KEYCLOAK_CLIENT_SECRET im Backend gesetzt
Berechtigungen Der Client benötigt Rechte zur Verwaltung der relevanten Organisationen und Benutzer

Frontend separat konfigurieren

Für die Anmeldung im Browser benötigt auch das Frontend einen Keycloak-Client mit erlaubten Redirect-URLs. Diese Konfiguration ist in der Frontend-Installationsanleitung beschrieben.

Umgebungsvariablen konfigurieren

Legen Sie im Verzeichnis der Docker-Compose-Datei eine .env-Datei an. Docker Compose liest diese Datei automatisch aus.

DB_USERNAME=chronoscope
DB_PASSWORD=<sicheres-datenbank-passwort>
MYSQL_ROOT_PASSWORD=<sicheres-root-passwort>

SMTP_HOST=smtp.example.org
SMTP_PORT=25

KEYCLOAK_URL=https://auth.example.org
KEYCLOAK_REALM=ni0
KEYCLOAK_CLIENT_ID=chronoscope-admin
KEYCLOAK_CLIENT_SECRET=<keycloak-client-secret>
Variable Bedeutung
DB_USERNAME Benutzername für die Datenbank
DB_PASSWORD Passwort des Datenbankbenutzers
MYSQL_ROOT_PASSWORD Root-Passwort für den MySQL-Container
SMTP_HOST Hostname oder IP-Adresse des SMTP-Servers
SMTP_PORT Port des SMTP-Servers, häufig 25 oder 587
KEYCLOAK_URL Basis-URL der Keycloak-Installation
KEYCLOAK_REALM Name des Keycloak-Realms
KEYCLOAK_CLIENT_ID Client-ID des Backend-Clients
KEYCLOAK_CLIENT_SECRET Client-Secret des Backend-Clients

Secrets schützen

Die .env-Datei enthält Passwörter und Secrets. Sie sollte nicht in ein Git-Repository eingecheckt und nur für Administratorinnen und Administratoren lesbar sein.

Backend mit Docker Compose starten

Die aktuelle Backend-Version kann als Container aus der GitHub Container Registry bezogen werden:

ChronoScope Backend Package

Mit folgender docker-compose.yml wird das Backend gemeinsam mit MySQL gestartet:

version: '3.9'

services:
  chronoscope-backend:
    image: ghcr.io/ni0-name-ideas-0/chronoscope-backend-backend:latest
    restart: always
    ports:
      - "127.0.0.1:9120:9020"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - SERVER_PORT=9020
      - DB_URL=jdbc:mysql://mysql:3306/chronoscope
      - DB_USERNAME=${DB_USERNAME}
      - DB_PASSWORD=${DB_PASSWORD}
      - SMTP_HOST=${SMTP_HOST}
      - SMTP_PORT=${SMTP_PORT}
      - KEYCLOAK_URL=${KEYCLOAK_URL}
      - KEYCLOAK_REALM=${KEYCLOAK_REALM}
      - KEYCLOAK_CLIENT_ID=${KEYCLOAK_CLIENT_ID}
      - KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET}
    depends_on:
      - mysql
    networks:
      - chrononet

  mysql:
    image: mysql:8.0
    restart: always
    environment:
      - MYSQL_DATABASE=chronoscope
      - MYSQL_USER=${DB_USERNAME}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - chrononet

volumes:
  mysql_data:

networks:
  chrononet:

Starten Sie anschließend die Container:

docker compose up -d

Prüfen Sie danach, ob die Container laufen:

docker compose ps

Die API ist in diesem Beispiel lokal auf dem Server unter http://127.0.0.1:9120 erreichbar. Nach außen sollte sie über einen Reverse Proxy und HTTPS veröffentlicht werden.

Portbindung

Die Compose-Datei bindet den Backend-Port bewusst nur an 127.0.0.1. Dadurch ist das Backend nicht direkt aus dem Internet erreichbar, sondern nur über den vorgeschalteten Reverse Proxy.

Externe Datenbank verwenden

Wenn der Kunde bereits eine Datenbank betreibt, kann der mysql-Service aus der Compose-Datei entfernt werden. Setzen Sie DB_URL, DB_USERNAME und DB_PASSWORD dann passend zur externen Datenbank.

Beispiel:

DB_URL=jdbc:mysql://db.example.internal:3306/chronoscope
DB_USERNAME=chronoscope
DB_PASSWORD=<sicheres-datenbank-passwort>

Der Datenbankserver muss vom Backend-Container aus erreichbar sein.

Reverse Proxy einrichten

Für den produktiven Zugriff sollte das Backend hinter einem Reverse Proxy betrieben werden. Das passt besonders gut, wenn das Frontend unter derselben Domain läuft und API-Aufrufe unter /api weitergeleitet werden.

Beispiel mit Nginx

server {
    listen 80;
    server_name chronoscope.example.org;

    location /api/ {
        proxy_pass http://127.0.0.1:9120/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Für den Produktivbetrieb sollte zusätzlich HTTPS aktiviert werden. Wenn Frontend und Backend unter derselben Domain laufen, kann der Frontend-Webserver dieselbe /api-Weiterleitung enthalten.

CORS konfigurieren

Das Backend erlaubt im Produktivprofil nur konfigurierte Ursprünge. In der Standardkonfiguration ist https://chronoscope.ni0.team eingetragen. Für eine Kundeninstallation muss die öffentlich genutzte Frontend-Adresse erlaubt werden.

Wenn die Anwendung unter https://chronoscope.example.org läuft, sollte dieser Ursprung in der Backend-Konfiguration hinterlegt sein:

cors:
  allowed-origins:
    - https://chronoscope.example.org

Wird das Backend als unverändertes Container-Image betrieben und das Frontend greift über dieselbe Domain auf /api zu, entsteht im Browser kein Cross-Origin-Aufruf. In diesem Fall ist in der Regel keine zusätzliche CORS-Freigabe nötig.

Keine Wildcards in Produktion

Verwenden Sie in der Produktivumgebung keine pauschale Freigabe wie *, wenn echte Benutzer- oder Organisationsdaten verarbeitet werden.

Betrieb prüfen

Nach dem Start sollten folgende Punkte geprüft werden:

Prüfung Erwartetes Ergebnis
Containerstatus prüfen Backend und Datenbank laufen
Logs prüfen Keine wiederholten Datenbank-, SMTP- oder Keycloak-Fehler
Backend lokal erreichen Reverse Proxy kann 127.0.0.1:9120 erreichen
Frontend anmelden Keycloak-Login funktioniert
API-Aufruf auslösen Aufgaben, Organisationen oder Identitätsdaten werden geladen
E-Mail-Funktion testen Einladung oder Account-Link-Mail wird versendet

Nützliche Befehle:

docker compose logs -f chronoscope-backend
docker compose restart chronoscope-backend
docker compose pull
docker compose up -d

Bereit für die Übergabe

Wenn Datenbankverbindung, Keycloak-Anmeldung, API-Aufrufe und E-Mail-Versand funktionieren, ist das Backend aus Sicht der Produktivbereitstellung einsatzbereit.

Häufige Probleme

Problem Mögliche Ursache Lösung
Backend startet nicht Pflichtvariable fehlt .env prüfen, besonders DB_PASSWORD und Keycloak-Secrets
Datenbankfehler beim Start Datenbank nicht erreichbar oder falsche Zugangsdaten DB_URL, Benutzername und Passwort prüfen
Login funktioniert, API liefert aber 401 Keycloak-Realm oder Token-Issuer passt nicht Realm, Frontend-Keycloak-Konfiguration und Backend-Keycloak-URL abgleichen
Organisationsfunktionen schlagen fehl Backend-Client hat zu wenige Rechte Berechtigungen des Keycloak-Clients prüfen
Browser meldet CORS-Fehler Frontend-Origin ist nicht erlaubt cors.allowed-origins passend zur Frontend-URL setzen
E-Mails werden nicht versendet SMTP-Host oder Port ist falsch SMTP-Erreichbarkeit aus dem Backend-Container prüfen