LocalDev-Keycloak umstellen auf Postgres #2

Open
opened 2026-07-13 07:15:28 +00:00 by boxi · 0 comments
Owner

Keycloak in localDev von H2 auf vorbereitete Postgres-Instanz umstellen

Typ: Task / Technical Improvement

Ausgangslage

Keycloak läuft in der lokalen Entwicklungsumgebung (deploy/localDev/boxit/docker-compose.yml) aktuell mit der eingebetteten H2-Datenbank:

  • Der Service startet mit command: - start-dev (docker-compose.yml:47-49). start-dev verwendet ohne explizite DB-Konfiguration Keycloaks embedded H2.
  • Die für Postgres vorbereitete Alternative ist auskommentiert
    (docker-compose.yml:48): #- start-dev --db postgres --db-url jdbc:postgresql://postgres:5432/keycloak --db-username keycloak --db-password keycloakpw.
  • Die passende Postgres-DB keycloak wird bereits beim Init angelegt
    (docker-compose.yml:24, via POSTGRES_MULTIPLE_DATABASES → keycloak:keycloakpw:keycloak), ist aber derzeit ungenutzt.

Probleme mit H2 in localDev

  • Kein persistenter, konsistenter Zustand: Realm, Clients, User und Rollen liegen im Container. Bei Image-Wechsel/Recreate ohne persistiertes Volume gehen sie verloren.
  • Divergenz zu prod: prod nutzt bereits Postgres (deploy/prod/docker-compose.yml:38-41: KC_DB=postgres, KC_DB_URL, KC_DB_USERNAME, KC_DB_PASSWORD). H2 in localDev testet einen anderen Persistenz-Layer als das, was produktiv läuft.
  • Die vorbereitete Postgres-Infrastruktur (keycloak-DB) liegt brach.

Ziel

Keycloak in localDev nutzt die bereits vorbereitete Postgres-DB keycloak statt H2. Der bestehende H2-Realm-Stand (boxit-Realm inkl. Clients/User) wird verlustfrei nach Postgres übernommen. Die localDev-Konfiguration ist damit näher an prod.

Vorgeschlagene Config-Änderung

In deploy/localDev/boxit/docker-compose.yml beim keycloak-Service. Zwei gleichwertige Varianten — im Ticket eine wählen:

Variante A — Env-Variablen (analog prod, empfohlen):

    environment:
      KC_BOOTSTRAP_ADMIN_USERNAME: 'develop'
      KC_BOOTSTRAP_ADMIN_PASSWORD: 'develop'
      KC_HTTP_ENABLED: 'true'
      KC_HOSTNAME: 'http://kubernetes.docker.internal:8081'
      KC_HOSTNAME_URL: 'http://kubernetes.docker.internal:8081'
      KC_HOSTNAME_ADMIN_URL: 'http://kubernetes.docker.internal:8081'
      KC_DB: postgres
      KC_DB_URL: 'jdbc:postgresql://postgres:5432/keycloak'
      KC_DB_USERNAME: 'keycloak'
      KC_DB_PASSWORD: 'keycloakpw'
    command:
      - start-dev

Variante B — Command-Flags (die bereits auskommentierte Zeile aktivieren):

    command:
      - start-dev --db postgres --db-url jdbc:postgresql://postgres:5432/keycloak --db-username keycloak --db-password keycloakpw

Variante A wird bevorzugt, weil sie exakt der prod-Struktur (deploy/prod/docker-compose.yml) entspricht und start-dev (Dev-Modus mit Postgres) beibehält.

Schritt-für-Schritt-Anleitung (Migration H2 → Postgres)

1. Vorbereitung / aktuellen Zustand sichern

  1. Sicherstellen, dass die aktuelle Umgebung läuft und der gewünschte H2-Stand aktiv ist:
    cd deploy/localDev/boxit && docker compose up -d
    
  2. Container-Namen des Keycloak-Services ermitteln (für die folgenden exec-Befehle):
    docker compose ps
    
    Im Folgenden <kc> = Keycloak-Container-Name.

2. Realm aus H2 exportieren

Export des laufenden Keycloak (H2) in eine Datei innerhalb des Containers. Beide Realms sichern (boxit + master) bzw. gezielt boxit:

# Export des boxit-Realms inkl. User in eine einzelne Datei
docker compose exec keycloak \
  /opt/keycloak/bin/kc.sh export \
  --realm boxit \
  --users realm_file \
  --file /tmp/boxit-realm-export.json

Hinweis: Der Export via kc.sh export verbindet sich mit der aktuell konfigurierten DB (H2), solange die Config noch nicht umgestellt ist. Deshalb vor der Config-Umstellung ausführen.

Export-Datei aus dem Container auf den Host kopieren (Backup / Import-Quelle):

docker compose cp keycloak:/tmp/boxit-realm-export.json ./keycloak/import/boxit-realm-export.json

3. Config auf Postgres umstellen

  1. docker-compose.yml gemäss Variante A (oben) anpassen: KC_DB, KC_DB_URL, KC_DB_USERNAME, KC_DB_PASSWORD ergänzen.
  2. Container mit neuer Config neu starten:
    docker compose up -d keycloak
    
  3. Prüfen, dass Keycloak jetzt gegen Postgres startet (keine H2-Meldungen), Logs kontrollieren:
    docker compose logs -f keycloak
    
  4. Verifizieren, dass die Keycloak-Tabellen in Postgres angelegt wurden:
    docker compose exec postgres \
      psql -U develop -d keycloak -c "\dt" | head
    
    (Keycloak legt sein Schema beim ersten Start selbst an.)

4. Realm nach Postgres importieren

Nach dem Umstellen ist die keycloak-DB leer (nur Keycloak-Schema, kein boxit-Realm). Import der zuvor exportierten Datei:

Empfohlen — Auto-Import beim Start (idempotent, nur wenn Realm noch nicht existiert):

  1. Export-Datei per Volume in den Import-Ordner mounten (docker-compose.yml, keycloak-Service):
        volumes:
          - ./keycloak/theme:/opt/keycloak/themes/boxit
          - ./keycloak/theme.v2:/opt/keycloak/themes/boxit.v2
          - ./keycloak/import:/opt/keycloak/data/import
    
  2. Command um --import-realm erweitern und neu starten:
        command:
          - start-dev --import-realm
    
    docker compose up -d keycloak
    

Alternative — manueller Einmal-Import (überschreibt/überspringt je nach Strategie):

docker compose exec keycloak \
  /opt/keycloak/bin/kc.sh import \
  --file /opt/keycloak/data/import/boxit-realm-export.json

5. Verifikation

  1. Keycloak-Admin-Konsole öffnen: http://localhost:8081 (Login develop / develop).
  2. Realm boxit vorhanden, Clients (apacheOIDC, account, …) und Test-User vorhanden.
  3. Login-Flow end-to-end testen über die Apache-OIDC-Proxy-Kette:
    • Frontend (http://localhost:4200) bzw. http://localhost/openidc → Login gegen Keycloak funktioniert.
  4. Persistenz prüfen: Keycloak-Container recreaten und sicherstellen, dass Realm/User erhalten bleiben:
    docker compose up -d --force-recreate keycloak
    
  5. Optional: In Postgres gegenprüfen, dass Realm-Daten persistiert sind:
    docker compose exec postgres \
      psql -U develop -d keycloak -c "SELECT name FROM realm;"
    

6. Aufräumen

  • Nach erfolgreichem Import --import-realm wieder entfernen (Import ist einmalig nötig), damit spätere manuelle Änderungen im Realm nicht bei jedem Start überschrieben/ignoriert werden.
  • Temporäre Export-Datei im Container (/tmp/boxit-realm-export.json) ist mit dem Container-Lifecycle weg; das Host-Backup unter keycloak/import/ behalten oder bewusst löschen.
  • Auskommentierte alte start-dev --db postgres …-Zeile in docker-compose.yml entfernen (durch gewählte Variante ersetzt).

Akzeptanzkriterien

  • Keycloak in localDev startet gegen die Postgres-DB keycloak (kein H2 mehr).
  • Der bestehende boxit-Realm inkl. Clients und Usern ist nach der Migration in Keycloak vorhanden.
  • Login-Flow (Frontend → Apache-OIDC → Keycloak → Backend) funktioniert unverändert.
  • Realm/User überleben ein docker compose up -d --force-recreate keycloak (Persistenz in Postgres).
  • docker-compose.yml ist aufgeräumt (keine tote auskommentierte DB-Zeile, --import-realm nach Einmal-Import entfernt).
  • localDev-Keycloak-Config entspricht strukturell der prod-Config (KC_DB*).

Risiken / Hinweise

  • Export vor Config-Umstellung: kc.sh export muss gegen die noch aktive H2-DB laufen, sonst wird ein leerer Realm exportiert.
  • Volume-Persistenz: Der Postgres-Service persistiert bereits in das Volume postgres (docker-compose.yml:2,25-26) — die Keycloak-Daten sind damit dauerhaft. Kein zusätzliches Volume nötig.
  • --import-realm-Strategie: Standard-Import legt den Realm nur an, wenn er nicht existiert. Für ein Überschreiben eines bereits importierten Realms explizit die Import-Strategie (OVERWRITE_EXISTING) beachten.
  • Bootstrap-Admin: KC_BOOTSTRAP_ADMIN_* legt den Admin nur beim ersten Init eines leeren Keycloak an. Nach Umstieg auf Postgres wird der Admin einmalig in der leeren keycloak-DB angelegt.
  • Keycloak-Version: Befehle beziehen sich auf das verwendete Image gitea.tail276105.ts.net/remsly/keycloak:4 (Keycloak-Quarkus-Distribution, kc.sh). Bei abweichender Version Export/Import-Flags gegenprüfen.
# Keycloak in localDev von H2 auf vorbereitete Postgres-Instanz umstellen **Typ:** Task / Technical Improvement ## Ausgangslage Keycloak läuft in der lokalen Entwicklungsumgebung (`deploy/localDev/boxit/docker-compose.yml`) aktuell mit der **eingebetteten H2-Datenbank**: - Der Service startet mit `command: - start-dev` (`docker-compose.yml:47-49`). `start-dev` verwendet ohne explizite DB-Konfiguration Keycloaks embedded H2. - Die für Postgres vorbereitete Alternative ist auskommentiert (`docker-compose.yml:48`): `#- start-dev --db postgres --db-url jdbc:postgresql://postgres:5432/keycloak --db-username keycloak --db-password keycloakpw`. - Die passende Postgres-DB **`keycloak`** wird bereits beim Init angelegt (`docker-compose.yml:24`, via `POSTGRES_MULTIPLE_DATABASES` → `keycloak:keycloakpw:keycloak`), ist aber derzeit ungenutzt. ### Probleme mit H2 in localDev - **Kein persistenter, konsistenter Zustand**: Realm, Clients, User und Rollen liegen im Container. Bei Image-Wechsel/Recreate ohne persistiertes Volume gehen sie verloren. - **Divergenz zu prod**: prod nutzt bereits Postgres (`deploy/prod/docker-compose.yml:38-41`: `KC_DB=postgres`, `KC_DB_URL`, `KC_DB_USERNAME`, `KC_DB_PASSWORD`). H2 in localDev testet einen anderen Persistenz-Layer als das, was produktiv läuft. - Die vorbereitete Postgres-Infrastruktur (`keycloak`-DB) liegt brach. ## Ziel Keycloak in localDev nutzt die **bereits vorbereitete Postgres-DB `keycloak`** statt H2. Der bestehende H2-Realm-Stand (`boxit`-Realm inkl. Clients/User) wird verlustfrei nach Postgres übernommen. Die localDev-Konfiguration ist damit näher an prod. ## Vorgeschlagene Config-Änderung In `deploy/localDev/boxit/docker-compose.yml` beim `keycloak`-Service. Zwei gleichwertige Varianten — im Ticket eine wählen: **Variante A — Env-Variablen (analog prod, empfohlen):** ```yaml environment: KC_BOOTSTRAP_ADMIN_USERNAME: 'develop' KC_BOOTSTRAP_ADMIN_PASSWORD: 'develop' KC_HTTP_ENABLED: 'true' KC_HOSTNAME: 'http://kubernetes.docker.internal:8081' KC_HOSTNAME_URL: 'http://kubernetes.docker.internal:8081' KC_HOSTNAME_ADMIN_URL: 'http://kubernetes.docker.internal:8081' KC_DB: postgres KC_DB_URL: 'jdbc:postgresql://postgres:5432/keycloak' KC_DB_USERNAME: 'keycloak' KC_DB_PASSWORD: 'keycloakpw' command: - start-dev ``` **Variante B — Command-Flags (die bereits auskommentierte Zeile aktivieren):** ```yaml command: - start-dev --db postgres --db-url jdbc:postgresql://postgres:5432/keycloak --db-username keycloak --db-password keycloakpw ``` Variante A wird bevorzugt, weil sie exakt der prod-Struktur (`deploy/prod/docker-compose.yml`) entspricht und `start-dev` (Dev-Modus mit Postgres) beibehält. ## Schritt-für-Schritt-Anleitung (Migration H2 → Postgres) ### 1. Vorbereitung / aktuellen Zustand sichern 1. Sicherstellen, dass die aktuelle Umgebung läuft und der gewünschte H2-Stand aktiv ist: ```bash cd deploy/localDev/boxit && docker compose up -d ``` 2. Container-Namen des Keycloak-Services ermitteln (für die folgenden `exec`-Befehle): ```bash docker compose ps ``` Im Folgenden `<kc>` = Keycloak-Container-Name. ### 2. Realm aus H2 exportieren Export des laufenden Keycloak (H2) in eine Datei innerhalb des Containers. Beide Realms sichern (`boxit` + `master`) bzw. gezielt `boxit`: ```bash # Export des boxit-Realms inkl. User in eine einzelne Datei docker compose exec keycloak \ /opt/keycloak/bin/kc.sh export \ --realm boxit \ --users realm_file \ --file /tmp/boxit-realm-export.json ``` > Hinweis: Der Export via `kc.sh export` verbindet sich mit der aktuell konfigurierten DB (H2), solange die Config noch nicht umgestellt ist. Deshalb **vor** der Config-Umstellung ausführen. Export-Datei aus dem Container auf den Host kopieren (Backup / Import-Quelle): ```bash docker compose cp keycloak:/tmp/boxit-realm-export.json ./keycloak/import/boxit-realm-export.json ``` ### 3. Config auf Postgres umstellen 1. `docker-compose.yml` gemäss **Variante A** (oben) anpassen: `KC_DB`, `KC_DB_URL`, `KC_DB_USERNAME`, `KC_DB_PASSWORD` ergänzen. 2. Container mit neuer Config neu starten: ```bash docker compose up -d keycloak ``` 3. Prüfen, dass Keycloak jetzt gegen Postgres startet (keine H2-Meldungen), Logs kontrollieren: ```bash docker compose logs -f keycloak ``` 4. Verifizieren, dass die Keycloak-Tabellen in Postgres angelegt wurden: ```bash docker compose exec postgres \ psql -U develop -d keycloak -c "\dt" | head ``` (Keycloak legt sein Schema beim ersten Start selbst an.) ### 4. Realm nach Postgres importieren Nach dem Umstellen ist die `keycloak`-DB leer (nur Keycloak-Schema, kein `boxit`-Realm). Import der zuvor exportierten Datei: Empfohlen — Auto-Import beim Start (idempotent, nur wenn Realm noch nicht existiert): 1. Export-Datei per Volume in den Import-Ordner mounten (`docker-compose.yml`, `keycloak`-Service): ```yaml volumes: - ./keycloak/theme:/opt/keycloak/themes/boxit - ./keycloak/theme.v2:/opt/keycloak/themes/boxit.v2 - ./keycloak/import:/opt/keycloak/data/import ``` 2. Command um `--import-realm` erweitern und neu starten: ```yaml command: - start-dev --import-realm ``` ```bash docker compose up -d keycloak ``` Alternative — manueller Einmal-Import (überschreibt/überspringt je nach Strategie): ```bash docker compose exec keycloak \ /opt/keycloak/bin/kc.sh import \ --file /opt/keycloak/data/import/boxit-realm-export.json ``` ### 5. Verifikation 1. Keycloak-Admin-Konsole öffnen: http://localhost:8081 (Login `develop` / `develop`). 2. Realm `boxit` vorhanden, Clients (`apacheOIDC`, `account`, …) und Test-User vorhanden. 3. Login-Flow end-to-end testen über die Apache-OIDC-Proxy-Kette: - Frontend (`http://localhost:4200`) bzw. `http://localhost/openidc` → Login gegen Keycloak funktioniert. 4. Persistenz prüfen: Keycloak-Container recreaten und sicherstellen, dass Realm/User erhalten bleiben: ```bash docker compose up -d --force-recreate keycloak ``` 5. Optional: In Postgres gegenprüfen, dass Realm-Daten persistiert sind: ```bash docker compose exec postgres \ psql -U develop -d keycloak -c "SELECT name FROM realm;" ``` ### 6. Aufräumen - Nach erfolgreichem Import `--import-realm` wieder entfernen (Import ist einmalig nötig), damit spätere manuelle Änderungen im Realm nicht bei jedem Start überschrieben/ignoriert werden. - Temporäre Export-Datei im Container (`/tmp/boxit-realm-export.json`) ist mit dem Container-Lifecycle weg; das Host-Backup unter `keycloak/import/` behalten oder bewusst löschen. - Auskommentierte alte `start-dev --db postgres …`-Zeile in `docker-compose.yml` entfernen (durch gewählte Variante ersetzt). ## Akzeptanzkriterien - [ ] Keycloak in localDev startet gegen die Postgres-DB `keycloak` (kein H2 mehr). - [ ] Der bestehende `boxit`-Realm inkl. Clients und Usern ist nach der Migration in Keycloak vorhanden. - [ ] Login-Flow (Frontend → Apache-OIDC → Keycloak → Backend) funktioniert unverändert. - [ ] Realm/User überleben ein `docker compose up -d --force-recreate keycloak` (Persistenz in Postgres). - [ ] `docker-compose.yml` ist aufgeräumt (keine tote auskommentierte DB-Zeile, `--import-realm` nach Einmal-Import entfernt). - [ ] localDev-Keycloak-Config entspricht strukturell der prod-Config (`KC_DB*`). ## Risiken / Hinweise - **Export vor Config-Umstellung**: `kc.sh export` muss gegen die noch aktive H2-DB laufen, sonst wird ein leerer Realm exportiert. - **Volume-Persistenz**: Der Postgres-Service persistiert bereits in das Volume `postgres` (`docker-compose.yml:2,25-26`) — die Keycloak-Daten sind damit dauerhaft. Kein zusätzliches Volume nötig. - **`--import-realm`-Strategie**: Standard-Import legt den Realm nur an, wenn er nicht existiert. Für ein Überschreiben eines bereits importierten Realms explizit die Import-Strategie (`OVERWRITE_EXISTING`) beachten. - **Bootstrap-Admin**: `KC_BOOTSTRAP_ADMIN_*` legt den Admin nur beim ersten Init eines leeren Keycloak an. Nach Umstieg auf Postgres wird der Admin einmalig in der leeren `keycloak`-DB angelegt. - **Keycloak-Version**: Befehle beziehen sich auf das verwendete Image `gitea.tail276105.ts.net/remsly/keycloak:4` (Keycloak-Quarkus-Distribution, `kc.sh`). Bei abweichender Version Export/Import-Flags gegenprüfen.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Remsly/Remsly#2
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.