Zum Hauptinhalt springen

Lokal entwickeln

Die Setup-Seite beschreibt, was ihr einmalig installiert. Diese Seite beschreibt den Alltag danach.

Die wichtigste Nachricht vorweg: Niemand braucht das gesamte System lokal. Ihr müsst weder PostgreSQL noch Keycloak installieren, und ihr müsst auch nicht die Services der anderen Teams starten, um an eurem eigenen zu arbeiten. Quarkus nimmt euch das ab.

In drei Schritten zum laufenden Service

docker info # prüfen, dass Docker läuft
cd services/urlaub # in euren Service wechseln
./mvnw quarkus:dev # starten

Wer die Quarkus CLI installiert hat, schreibt stattdessen nur quarkus dev.

Beim ersten Start dauert das etwas, weil Container-Images geladen werden. Danach passiert Folgendes automatisch:

WasWo
Euer Servicehttp://localhost:8080
Dev UIhttp://localhost:8080/q/dev-ui
PostgreSQL-Containerwird gestartet und verdrahtet
Keycloak-Containerwird gestartet und verdrahtet

Ihr habt an dieser Stelle eine vollständige Entwicklungsumgebung, ohne eine einzige Zugangsdatei angelegt zu haben.

Dev Mode und Live Reload

Der Dev Mode ist kein Server, den ihr nach jeder Änderung neu startet. Ihr speichert die Datei, ladet den Browser neu, und Quarkus hat den geänderten Code bereits übernommen. Das gilt auch für Änderungen an der application.properties.

In der Konsole steuert ihr den laufenden Dev Mode über Tastenkürzel:

TasteWirkung
hAlle verfügbaren Befehle anzeigen
rContinuous Testing starten oder anhalten
dDev UI im Browser öffnen
wDie Anwendung im Browser öffnen
sNeustart erzwingen
qBeenden
Den Dev Mode laufen lassen

Beendet ihn nicht nach jeder Änderung. Er ist dafür gebaut, den ganzen Arbeitstag zu laufen. Ein Neustart ist nur nötig, wenn ihr Abhängigkeiten in der pom.xml ändert.

Dev Services: Datenbank und Keycloak ohne Installation

Dev Services startet die Infrastruktur, die euer Service braucht, automatisch als Container, sobald die zugehörige Verbindung nicht konfiguriert ist. Intern läuft das über Testcontainers.

Der entscheidende Punkt ist die Bedingung „nicht konfiguriert". Genau deshalb ist die application.properties im Projekt fast leer, und genau deshalb soll sie das bleiben:

src/main/resources/application.properties
# Hibernate verwaltet das Schema
quarkus.hibernate-orm.database.generation=update

# Im Test mit leerem Schema starten
%test.quarkus.hibernate-orm.database.generation=drop-and-create

Weder Datenbank-URL noch auth-server-url stehen darin. In Produktion kommen sie über Umgebungsvariablen wie QUARKUS_DATASOURCE_JDBC_URL herein, lokal ist damit nichts gesetzt, und Quarkus startet die Container selbst.

Die Datei nicht mit Platzhaltern füllen

Etwas wie quarkus.datasource.jdbc.url=${DB_URL} in die Datei zu schreiben sieht harmlos aus, kostet euch aber genau diesen Komfort: Die Einstellung gilt damit als gesetzt, Dev Services springt nicht mehr an, und ihr müsst PostgreSQL wieder von Hand betreiben.

Die Details zu den einzelnen Diensten stehen in den Guides zu Dev Services für Datenbanken und Dev Services für Keycloak.

Docker muss laufen

Ohne laufende Container-Runtime scheitert der Start mit einer Meldung über eine nicht gefundene Docker-Umgebung. Das ist der mit Abstand häufigste Fehler beim ersten Versuch. Die Installation beschreibt die Setup-Seite.

Ein Keycloak für alle Services

Arbeitet ihr an mehreren Services gleichzeitig, würde naiv gedacht jeder seinen eigenen Keycloak starten. Das passiert nicht: Keycloak Dev Services erkennt einen bereits laufenden Container am Label quarkus-dev-service-keycloak und teilt ihn standardmäßig zwischen allen lokal laufenden Quarkus-Anwendungen.

Drei parallel laufende Services bedeuten also einen Keycloak, nicht drei:

Der zuerst gestartete Service bringt den Container hoch, alle weiteren finden ihn über das Label und hängen sich an. Ihr müsst dafür nichts konfigurieren. Abschalten ließe sich das Verhalten über quarkus.keycloak.devservices.shared=false, aber das wollt ihr in diesem Projekt nicht.

Euer eigenes Realm lokal verwenden

Standardmäßig legt der Keycloak Dev Service ein Realm mit den Testnutzern alice und bob an. Sobald ihr eigene Rollen benutzt, reicht das nicht mehr, und es entsteht der Klassiker: Auf dem Server greift die Berechtigung, lokal nicht.

Die Lösung ist eine Realm-Datei im Repository:

quarkus.keycloak.devservices.realm-path=winfprojekt-realm.json

Liegt die Datei unter src/main/resources/, importiert der Dev Service sie beim Start. Damit entwickelt das ganze Team gegen dieselben Rollen, Clients und Testnutzer wie auf dem Server, und die Definition liegt versioniert im Git statt in der Erinnerung einer einzelnen Person.

Ein Realm exportiert ihr aus der Keycloak-Adminkonsole unter Realm settings, Menü Action, Partial export. Nehmt Clients und Rollen mit, aber keine echten Nutzerdaten.

Keine echten Zugangsdaten in die Realm-Datei

Die Datei landet im öffentlichen Repository. Sie darf ausschließlich Testnutzer mit offensichtlichen Testpasswörtern enthalten, niemals Passwörter oder Client Secrets aus der Produktivumgebung.

Die Dev UI

Unter http://localhost:8080/q/dev-ui liegt der Werkzeugkasten, den die meisten übersehen. Was dort alles steckt, beschreibt der Guide Dev UI:

BereichWofür
ConfigurationAlle wirksamen Konfigurationswerte einsehen und im laufenden Betrieb ändern
OpenID ConnectSich am Keycloak Dev Service anmelden und geschützte Endpunkte ausprobieren
Dev ServicesSehen, welche Container laufen und unter welchen Zugangsdaten
Continuous TestingTestergebnisse live mitverfolgen

Wie ihr darüber geschützte Endpunkte manuell testet, steht auf der Testing-Seite.

In die Datenbank schauen

Früher oder später wollt ihr wissen, was tatsächlich in der Datenbank steht. Etwa weil Hibernate ein Schema anders angelegt hat als erwartet, oder weil ein Datensatz nicht so aussieht wie gedacht. Der Dev-Service-Container ist dafür ganz normal erreichbar, ihr müsst nur die Zugangsdaten kennen.

Zugangsdaten finden

Der einfachste Weg führt über die Dev UI: Unter http://localhost:8080/q/dev-ui zeigt die Karte Dev Services die vollständige JDBC-URL samt Benutzername und Passwort des laufenden Containers an. Alternativ verrät docker ps den Port, auf den der Container nach außen gemappt ist.

Der Haken daran: Dev Services vergibt standardmäßig bei jedem Start einen zufälligen Port. Eine einmal gespeicherte Verbindung im Datenbankwerkzeug funktioniert dann beim nächsten Mal nicht mehr. Deshalb lohnt sich ein fester Port für die Entwicklung:

%dev.quarkus.datasource.devservices.port=5432

Damit ist die Verbindung dauerhaft jdbc:postgresql://localhost:5432/... und ihr richtet sie im Werkzeug genau einmal ein.

IntelliJ IDEA

IntelliJ bringt in der Ultimate Edition ein Datenbankwerkzeug mit, das für diesen Zweck vollkommen ausreicht:

  1. View, Tool Windows, Database öffnen
  2. Über + eine Data Source vom Typ PostgreSQL anlegen
  3. Host localhost, Port wie oben festgelegt, Datenbank, Benutzer und Passwort aus der Dev UI übernehmen
  4. Beim ersten Mal den PostgreSQL-Treiber herunterladen lassen, dann Test Connection

Danach seht ihr die Tabellen im Projektbaum, könnt Daten direkt ansehen und eigene SQL-Abfragen ausführen. Die Einrichtung der IDE beschreibt die Setup-Seite.

Community Edition hat kein Datenbankwerkzeug

Das Database-Fenster gibt es nur in der Ultimate Edition. Studierende erhalten sie kostenlos über die JetBrains-Lizenz für Bildungseinrichtungen. Wer die Community Edition nutzt, greift zu einem der folgenden Werkzeuge.

Alternativen

WerkzeugAnmerkung
DBeaver CommunityKostenlos, plattformübergreifend, funktioniert genauso
pgAdminSpeziell für PostgreSQL, umfangreicher, aber schwergewichtiger
psql im ContainerOhne Installation: Container mit docker ps heraussuchen, dann docker exec -it <container> psql -U quarkus -d quarkus
Die Daten sind flüchtig

Der Dev-Service-Container wird verworfen, wenn ihr ihn entfernt, und mit %test.quarkus.hibernate-orm.database.generation=drop-and-create startet jeder Testlauf ohnehin mit leerem Schema. Alles, was ihr dort von Hand anlegt, ist Wegwerfware. Testdaten, die ihr regelmäßig braucht, gehören als Import-Skript ins Repository.

Continuous Testing

Im Dev Mode startet ihr mit r die kontinuierliche Testausführung. Nach jedem Speichern laufen nur die Tests, die vom geänderten Code betroffen sind. Ihr merkt damit innerhalb von Sekunden, wenn ihr etwas kaputt gemacht habt, statt es im Pull Request zu erfahren. Was ihr dafür schreibt, beschreibt die Testing-Seite.

Mehrere Services gleichzeitig starten

Alle Services belegen standardmäßig Port 8080, was beim zweiten Start scheitert. Vergebt deshalb pro Service einen festen Port, nur für das Dev-Profil. Das %dev.-Präfix ist ein Konfigurationsprofil und bedeutet, dass die Zeile ausschließlich im Dev Mode gilt:

%dev.quarkus.http.port=8081

Haltet die Zuordnung im Team fest, damit alle dieselbe Vorstellung davon haben, was wo läuft:

ServicePort
Urlaubsservice8080
Rechnungsservice8081
Stammdatenservice8082

Frontend gegen lokales Backend

Startet ihr das React-Frontend mit npm run dev, läuft es auf Port 5173 und der Service auf 8080. Ein direkter Aufruf scheitert dann an CORS.

Die richtige Lösung ist nicht, CORS im Backend aufzuweichen, sondern der Proxy des Vite-Entwicklungsservers:

vite.config.ts
export default defineConfig({
plugins: [react()],
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});

Im Anwendungscode ruft ihr dann /api/urlaubsantraege auf:

Der entscheidende Punkt ist die linke Seite: Der Browser spricht ausschließlich mit Port 5173. Die Weiterleitung auf 8080 passiert im Vite-Server, also serverseitig und außerhalb der Reichweite der Same-Origin-Regel. Für den Browser kommt alles von derselben Adresse, CORS entfällt. In Produktion zeigt VITE_API_URL weiterhin auf die echte Subdomain hinter dem Reverse Proxy.

Was Dev Services nicht abdeckt

Für alles, was kein Quarkus kennt, braucht ihr eine Entscheidung. Der Leitgedanke bleibt: so wenig wie möglich lokal betreiben.

FallEmpfehlung
CIB sevenEigenes docker-compose.yml für lokal, oder gegen die Instanz auf dem Server arbeiten. Details auf der CIB seven-Seite
Service eines anderen TeamsGegen die Testumgebung zeigen lassen. Nur wenn das nicht geht, mit der WireMock-Extension die Antworten nachstellen
Externe APIEbenfalls WireMock, damit eure Tests nicht vom Netz abhängen

Wenn es nicht startet

SymptomUrsache und Lösung
Could not find a valid Docker environmentDocker läuft nicht. Docker Desktop starten und mit docker info prüfen
Port 8080 already in useEin anderer Dev Mode läuft noch. Beenden, oder %dev.quarkus.http.port setzen
Login schlägt nach Änderung der Realm-Datei fehlDer geteilte Keycloak-Container läuft noch mit dem alten Realm. Mit docker ps --filter label=quarkus-dev-service-keycloak finden und entfernen
Änderungen wirken nichtBei Änderungen an der pom.xml greift Live Reload nicht. Dev Mode neu starten
Erster Start dauert sehr langeDie Container-Images werden geladen. Das passiert nur einmal pro Image-Version
Datenbank enthält alte TestdatenDer Dev-Service-Container lebt über Neustarts hinweg. Container entfernen, dann startet er leer

Offizielle Dokumentation

Alles auf dieser Seite ist eine auf dieses Projekt zugeschnittene Auswahl. Die vollständige Referenz steht bei Quarkus:

ThemaGuide
Dev Mode und Live ReloadMaven Tooling
Dev Services im ÜberblickDev Services
Datenbank-ContainerDev Services for Databases
Keycloak-Container und Realm-ImportDev Services and Dev UI for OIDC
Die Dev UIDev UI
Tests im HintergrundContinuous Testing
Konfigurationsprofile wie %dev. und %test.Configuration Reference, Profiles
Wie Umgebungsvariablen auf Properties abgebildet werdenConfiguration Reference, Environment variables
Jede einzelne EinstellungAll Configuration Options
Die KommandozeileQuarkus CLI