From edce9606513e23d693dfbc0d777f47daa7e93ed8 Mon Sep 17 00:00:00 2001 From: mgarciaLKS Date: Mon, 2 Feb 2026 17:12:09 +0100 Subject: [PATCH 1/7] Add migration guide for transitioning from Bitnami Keycloak to CloudPirates Keycloak --- ...O_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md | 466 ++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100644 migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md diff --git a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md new file mode 100644 index 00000000..13da250d --- /dev/null +++ b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md @@ -0,0 +1,466 @@ +# Migration Guide: Bitnami Keycloak → CloudPirates Keycloak + +**Version**: Keycloak 25.x (Bitnami) → Keycloak 26.x (CloudPirates) + +> ⚠️ **Important**: This migration requires downtime. Schedule a maintenance window. + +## Overview + +This guide covers migrating from the Bitnami Keycloak Helm chart to the CloudPirates Keycloak Helm chart. CloudPirates provides a lighter, more maintainable chart using the official Keycloak image. + +### Key Differences + +| Aspect | Bitnami | CloudPirates | +|--------|---------|--------------| +| Image | `bitnami/keycloak` (custom) | `keycloak/keycloak` (official) | +| Chart version | 23.x | 0.13.x | +| Keycloak version | 25.x | 26.x | +| Configuration style | Flat structure | Nested under `keycloak.*` | +| Themes path | `/opt/bitnami/keycloak/themes/` | `/opt/keycloak/themes/` | + +--- + +## Chart.yaml Changes + +Update your Keycloak dependency: + +```yaml +# Before (Bitnami) +dependencies: + - condition: keycloak.enabled + name: keycloak + repository: oci://registry-1.docker.io/bitnamicharts + version: 23.0.0 + +# After (CloudPirates) +dependencies: + - condition: keycloak.enabled + name: keycloak + repository: oci://registry-1.docker.io/cloudpirates + version: 0.13.6 +``` + +--- + +## Configuration Mapping + +### Admin Configuration + +| Bitnami | CloudPirates | Notes | +|---------|--------------|-------| +| `keycloak.auth.adminUser` | `keycloak.keycloak.adminUser` | Nested under `keycloak` | +| `keycloak.auth.adminPassword` | `keycloak.keycloak.adminPassword` | | +| `keycloak.auth.existingSecret` | `keycloak.keycloak.existingSecret` | | + +### Server Configuration + +| Bitnami | CloudPirates | Notes | +|---------|--------------|-------| +| `keycloak.proxy` | `keycloak.keycloak.proxyHeaders` | Values: `xforwarded`, `forwarded` | +| `keycloak.production` | `keycloak.keycloak.production` | | +| `keycloak.httpRelativePath` | `keycloak.keycloak.httpRelativePath` | **No trailing slash!** Use `/auth` not `/auth/` | + +### Database Configuration + +| Bitnami | CloudPirates | Notes | +|---------|--------------|-------| +| `keycloak.postgresql.enabled` | `keycloak.postgres.enabled` | Subchart name changed | +| `keycloak.externalDatabase.host` | `keycloak.database.host` | | +| `keycloak.externalDatabase.port` | `keycloak.database.port` | | +| `keycloak.externalDatabase.database` | `keycloak.database.name` | | +| `keycloak.externalDatabase.user` | Via `existingSecret` | See below | +| `keycloak.externalDatabase.password` | Via `existingSecret` | See below | +| `keycloak.externalDatabase.existingSecret` | `keycloak.database.existingSecret` | Different key names | + +### Database Secret Format + +**Critical Change**: CloudPirates expects different secret keys: + +| Bitnami Keys | CloudPirates Keys | +|--------------|-------------------| +| `password` or custom | `db-password` | +| `username` or custom | `db-username` | + +Create a secret with the correct format: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: keycloak-db-secret +type: Opaque +stringData: + db-username: "your_db_user" + db-password: "your_db_password" +``` + +### Ingress Configuration + +| Bitnami | CloudPirates | Notes | +|---------|--------------|-------| +| `keycloak.ingress.hostname` | `keycloak.ingress.hosts[].host` | Array format | +| `keycloak.ingress.tls: true` | `keycloak.ingress.tls: []` | Array of TLS configs | + +**Bitnami format:** +```yaml +keycloak: + ingress: + enabled: true + hostname: keycloak.example.com + tls: true +``` + +**CloudPirates format:** +```yaml +keycloak: + ingress: + enabled: true + hosts: + - host: keycloak.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: keycloak-tls + hosts: + - keycloak.example.com +``` + +### Init Containers & Volumes + +| Bitnami | CloudPirates | +|---------|--------------| +| `keycloak.initContainers` | `keycloak.extraInitContainers` | +| `keycloak.extraVolumes` | `keycloak.extraVolumes` | +| `keycloak.extraVolumeMounts` | `keycloak.extraVolumeMounts` | + +**Path changes for volume mounts:** +- Bitnami: `/opt/bitnami/keycloak/...` +- CloudPirates: `/opt/keycloak/...` + +--- + +## Common Issues & Solutions + +### 1. Pod Shows 0/1 Ready - Readiness Probe Fails + +**Symptom**: Pod status shows `0/1` but Keycloak appears to be running + +**Cause**: Double slash in readiness probe path (`/auth//realms/master`) + +**Solution**: Use `httpRelativePath` without trailing slash: +```yaml +keycloak: + keycloak: + httpRelativePath: /auth # NOT /auth/ +``` + +The chart concatenates `httpRelativePath + /realms/master`: +- `/auth` → `/auth/realms/master` ✅ +- `/auth/` → `/auth//realms/master` ❌ + +### 2. Database Authentication Failed + +**Symptom**: `password authentication failed for user` + +**Cause**: CloudPirates expects secret keys `db-username` and `db-password` + +**Solution**: Create secret with correct keys: +```yaml +stringData: + db-username: "keycloak_user" + db-password: "keycloak_password" +``` + +### 3. Database Connection Refused + +**Symptom**: `Connection to localhost:5432 refused` + +**Cause**: `database.host` not configured + +**Solution**: Set the correct database host: +```yaml +keycloak: + database: + host: "your-postgresql-service" + port: 5432 + name: keycloak +``` + +### 4. Theme Not Loading + +**Symptom**: Login page shows default Keycloak theme + +**Cause**: Theme path changed + +**Solution**: Update volume mounts: +```yaml +keycloak: + extraVolumeMounts: + - name: themes + mountPath: /opt/keycloak/themes/custom-theme # NOT /opt/bitnami/... +``` + +### 5. Proxy/SSL Issues + +**Symptom**: Redirect loops or SSL errors + +**Solution**: Update proxy configuration: +```yaml +# Bitnami +keycloak: + proxy: edge + +# CloudPirates +keycloak: + keycloak: + proxyHeaders: "xforwarded" +``` + +--- + +## Migration Steps + +### Step 1: Backup Current Installation + +```bash +# Get the Keycloak admin password +KEYCLOAK_PASSWORD=$(kubectl get secret -keycloak -n \ + -o jsonpath="{.data.admin-password}" | base64 --decode) + +# Port forward to Keycloak +kubectl port-forward svc/-keycloak 8080:80 -n & + +# Access Admin Console and export realm: +# 1. Navigate to http://localhost:8080/auth/admin +# 2. Login with admin credentials +# 3. Go to Realm Settings → Action → Partial Export +# 4. Select all options and export to JSON + +# If using dedicated PostgreSQL, backup the database: +kubectl exec -n -- \ + pg_dump -U keycloak -d keycloak > keycloak_backup.sql +``` + +### Step 2: Update Chart.yaml + +Change the Keycloak dependency: + +```yaml +# Before (Bitnami) +dependencies: + - condition: keycloak.enabled + name: keycloak + repository: oci://registry-1.docker.io/bitnamicharts + version: 23.0.0 + +# After (CloudPirates) +dependencies: + - condition: keycloak.enabled + name: keycloak + repository: oci://registry-1.docker.io/cloudpirates + version: 0.13.6 +``` + +### Step 3: Update values.yaml + +Migrate configuration using the mapping tables above. Key changes: + +```yaml +keycloak: + # Image (CloudPirates uses official image) + image: + tag: "26.5.2" + + # Admin config - nested under keycloak.* + keycloak: + adminUser: admin + adminPassword: "your-password" + proxyHeaders: "xforwarded" # Was: proxy: edge + production: false + httpRelativePath: /auth # NO trailing slash! + + # Database - different structure + database: + type: postgres + host: "postgresql-service" + name: keycloak + existingSecret: "keycloak-db-secret" # Must have db-username, db-password keys + + postgres: + enabled: false # Use external PostgreSQL +``` + +### Step 4: Create Database Secret + +CloudPirates requires specific secret keys: + +```bash +kubectl create secret generic keycloak-db-secret -n \ + --from-literal=db-username="keycloak_user" \ + --from-literal=db-password="your_db_password" +``` + +Or via template: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: keycloak-db-secret +type: Opaque +stringData: + db-username: "keycloak_user" + db-password: "your_db_password" +``` + +### Step 5: Update Volume Mounts (if using custom themes) + +```yaml +# Before (Bitnami) +extraVolumeMounts: + - name: themes + mountPath: /opt/bitnami/keycloak/themes/custom + +# After (CloudPirates) +extraVolumeMounts: + - name: themes + mountPath: /opt/keycloak/themes/custom +``` + +### Step 6: Uninstall Current Deployment + +```bash +# Uninstall current Keycloak +helm uninstall -n + +# Optional: Delete PVCs if you want a clean start +kubectl delete pvc data--keycloak-0 -n + +# Wait for pods to terminate +kubectl wait --for=delete pod/-keycloak-0 -n --timeout=120s +``` + +### Step 7: Deploy CloudPirates Keycloak + +```bash +# Update dependencies +helm dependency update + +# Install new version +helm install . -n + +# Wait for Keycloak to be ready +kubectl wait --for=condition=ready pod/-keycloak-0 -n --timeout=600s +``` + +### Step 8: Verify Migration + +```bash +# Check pod status +kubectl get pods -n + +# Check Keycloak version +kubectl logs -keycloak-0 -n | head -20 + +# Port forward and test +kubectl port-forward svc/-keycloak 8080:80 -n & + +# Verify Keycloak is responding +curl -s http://localhost:8080/auth/realms/master | jq .realm + +# Access admin console +echo "Admin Console: http://localhost:8080/auth/admin" +``` + +### Step 9: Import Realm (if needed) + +If realm was not auto-imported, use the backup from Step 1: + +```bash +# Via Admin Console: +# 1. Go to http://localhost:8080/auth/admin +# 2. Create realm → Import → Select your backup JSON + +# Or via keycloak-config-cli: +kubectl run realm-import --rm -i --restart=Never \ + --image=adorsys/keycloak-config-cli:latest-26 \ + --env="KEYCLOAK_URL=http://-keycloak" \ + --env="KEYCLOAK_USER=admin" \ + --env="KEYCLOAK_PASSWORD=" \ + -- java -jar /app/keycloak-config-cli.jar --import.files.locations=/realm.json +``` + +--- + +## Migration Checklist + +- [ ] Backup existing realm data (export from Admin Console) +- [ ] Backup database (if applicable) +- [ ] Update `Chart.yaml` dependency +- [ ] Update `values.yaml` configuration structure +- [ ] Create/update database secret with `db-username`/`db-password` keys +- [ ] Update volume mount paths (`/opt/bitnami/` → `/opt/keycloak/`) +- [ ] Update ingress configuration to array format +- [ ] Remove trailing slash from `httpRelativePath` +- [ ] Run `helm dependency update` +- [ ] Deploy and verify + +--- + +## Quick Reference: values.yaml Template + +```yaml +keycloak: + enabled: true + + image: + tag: "26.5.2" + + replicaCount: 1 + + keycloak: + adminUser: admin + adminPassword: "your-admin-password" + # existingSecret: "keycloak-admin-secret" + proxyHeaders: "xforwarded" + production: false + httpRelativePath: /auth # No trailing slash! + + database: + type: postgres + host: "postgresql-service" + port: 5432 + name: keycloak + existingSecret: "keycloak-db-secret" + + postgres: + enabled: false # Use external PostgreSQL + + ingress: + enabled: true + hosts: + - host: keycloak.example.com + paths: + - path: / + pathType: Prefix + tls: + - secretName: keycloak-tls + hosts: + - keycloak.example.com + + extraVolumes: + - name: themes + emptyDir: {} + + extraVolumeMounts: + - name: themes + mountPath: /opt/keycloak/themes/custom +``` + +--- + +## NOTICE + +This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). + +- SPDX-License-Identifier: CC-BY-4.0 +- SPDX-FileCopyrightText: 2025 Contributors to the Eclipse Foundation From 70ac1df97732831ce9df618e1e983e43730ecf3e Mon Sep 17 00:00:00 2001 From: mgarciaLKS Date: Mon, 2 Feb 2026 17:23:01 +0100 Subject: [PATCH 2/7] Refine migration guide for Bitnami Keycloak to CloudPirates Keycloak, enhancing clarity and adding detailed steps for configuration and deployment. --- ...O_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md | 394 ++++++++---------- 1 file changed, 185 insertions(+), 209 deletions(-) diff --git a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md index 13da250d..53465b0b 100644 --- a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md +++ b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md @@ -1,35 +1,59 @@ -# Migration Guide: Bitnami Keycloak → CloudPirates Keycloak +# Generic Migration Guide: Bitnami Keycloak → CloudPirates Keycloak **Version**: Keycloak 25.x (Bitnami) → Keycloak 26.x (CloudPirates) > ⚠️ **Important**: This migration requires downtime. Schedule a maintenance window. -## Overview +This guide provides generic migration instructions for any project using the Bitnami Keycloak Helm chart that wants to migrate to CloudPirates. For Industry Core Hub specific instructions, see the [ICHub Migration Guide](./BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md). -This guide covers migrating from the Bitnami Keycloak Helm chart to the CloudPirates Keycloak Helm chart. CloudPirates provides a lighter, more maintainable chart using the official Keycloak image. +--- -### Key Differences +## Why Migrate? | Aspect | Bitnami | CloudPirates | |--------|---------|--------------| -| Image | `bitnami/keycloak` (custom) | `keycloak/keycloak` (official) | -| Chart version | 23.x | 0.13.x | -| Keycloak version | 25.x | 26.x | -| Configuration style | Flat structure | Nested under `keycloak.*` | -| Themes path | `/opt/bitnami/keycloak/themes/` | `/opt/keycloak/themes/` | +| Docker Image | Custom Bitnami image | Official Keycloak image | +| Maintenance | Bitnami wrapper layer | Direct from Keycloak team | +| Keycloak Version | 25.x | 26.x (latest) | +| Chart Complexity | Heavy, many features | Lightweight, focused | +| Future Support | May lag behind upstream | Tracks upstream closely | --- -## Chart.yaml Changes +## Migration Steps + +### Step 1: Backup Current Installation + +```bash +# Get the Keycloak admin password +KEYCLOAK_PASSWORD=$(kubectl get secret -keycloak -n \ + -o jsonpath="{.data.admin-password}" | base64 --decode) + +# Port forward to Keycloak +kubectl port-forward svc/-keycloak 8080:80 -n & + +# Export realm from Admin Console: +# 1. Navigate to http://localhost:8080/auth/admin +# 2. Login with admin credentials +# 3. Go to Realm Settings → Action → Partial Export +# 4. Select all options and export to JSON +# 5. Save the JSON file + +# If using dedicated PostgreSQL, backup the database: +kubectl exec -n -- \ + pg_dump -U keycloak -d keycloak > keycloak_backup.sql +``` + +### Step 2: Update Chart.yaml -Update your Keycloak dependency: +Change the Keycloak dependency: ```yaml # Before (Bitnami) dependencies: - condition: keycloak.enabled name: keycloak - repository: oci://registry-1.docker.io/bitnamicharts + repository: oci://registry-1.docker.io/bitnamicharts # or https://raw.githubusercontent.com/bitnami/charts/... version: 23.0.0 # After (CloudPirates) @@ -40,6 +64,140 @@ dependencies: version: 0.13.6 ``` +### Step 3: Update values.yaml + +Migrate your configuration using the [Configuration Mapping](#configuration-mapping) below. + +**Key changes to make:** + +```yaml +keycloak: + # Image (CloudPirates uses official image) + image: + tag: "26.5.2" + + # Admin config - now nested under keycloak.* + keycloak: + adminUser: admin + adminPassword: "your-password" + proxyHeaders: "xforwarded" # Was: proxy: edge + production: false + httpRelativePath: /auth # NO trailing slash! + + # Database - different structure + database: + type: postgres + host: "postgresql-service" + name: keycloak + existingSecret: "keycloak-db-secret" # Must have db-username, db-password keys + + postgres: + enabled: false # Use external PostgreSQL +``` + +### Step 4: Create Database Secret + +CloudPirates requires a secret with specific keys: + +```bash +kubectl create secret generic keycloak-db-secret -n \ + --from-literal=db-username="keycloak_user" \ + --from-literal=db-password="your_db_password" +``` + +Or create a template: +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: keycloak-db-secret +type: Opaque +stringData: + db-username: "keycloak_user" + db-password: "your_db_password" +``` + +### Step 5: Update Init Containers and Volume Mounts + +Update paths from `/opt/bitnami/keycloak/` to `/opt/keycloak/`: + +```yaml +# Before (Bitnami) +initContainers: + - name: import + volumeMounts: + - name: themes + mountPath: /opt/bitnami/keycloak/themes/custom + +# After (CloudPirates) +extraInitContainers: + - name: import-themes + volumeMounts: + - name: themes + mountPath: /opt/keycloak/themes/custom +``` + +### Step 6: Uninstall Current Deployment + +```bash +# Uninstall current Keycloak +helm uninstall -n + +# Wait for pods to terminate +kubectl wait --for=delete pod/-keycloak-0 -n --timeout=120s + +# Optional: Delete PVCs if you want a clean start +# kubectl delete pvc data--keycloak-0 -n +``` + +### Step 7: Deploy CloudPirates Keycloak + +```bash +# Update dependencies +helm dependency update + +# Install new version +helm install . -n + +# Wait for Keycloak to be ready +kubectl wait --for=condition=ready pod/-keycloak-0 -n --timeout=600s +``` + +### Step 8: Verify Migration + +```bash +# Check pod status +kubectl get pods -n + +# Port forward and test +kubectl port-forward svc/-keycloak 8080:80 -n & + +# Verify Keycloak is responding +curl -s http://localhost:8080/auth/realms/master | jq .realm + +# Access admin console +echo "Admin Console: http://localhost:8080/auth/admin" +``` + +### Step 9: Import Realm (if needed) + +If realm was not auto-imported, use the backup from Step 1: + +```bash +# Via Admin Console: +# 1. Go to http://localhost:8080/auth/admin +# 2. Create realm → Import → Select your backup JSON + +# Or via keycloak-config-cli: +kubectl run realm-import --rm -i --restart=Never \ + --image=adorsys/keycloak-config-cli:latest-26 \ + -- java -jar /app/keycloak-config-cli.jar \ + --keycloak.url=http://-keycloak \ + --keycloak.user=admin \ + --keycloak.password= \ + --import.files.locations=/realm.json +``` + --- ## Configuration Mapping @@ -68,11 +226,9 @@ dependencies: | `keycloak.externalDatabase.host` | `keycloak.database.host` | | | `keycloak.externalDatabase.port` | `keycloak.database.port` | | | `keycloak.externalDatabase.database` | `keycloak.database.name` | | -| `keycloak.externalDatabase.user` | Via `existingSecret` | See below | -| `keycloak.externalDatabase.password` | Via `existingSecret` | See below | -| `keycloak.externalDatabase.existingSecret` | `keycloak.database.existingSecret` | Different key names | +| `keycloak.externalDatabase.existingSecret` | `keycloak.database.existingSecret` | Different key names! | -### Database Secret Format +### Database Secret Keys **Critical Change**: CloudPirates expects different secret keys: @@ -81,18 +237,6 @@ dependencies: | `password` or custom | `db-password` | | `username` or custom | `db-username` | -Create a secret with the correct format: -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: keycloak-db-secret -type: Opaque -stringData: - db-username: "your_db_user" - db-password: "your_db_password" -``` - ### Ingress Configuration | Bitnami | CloudPirates | Notes | @@ -132,10 +276,7 @@ keycloak: | `keycloak.initContainers` | `keycloak.extraInitContainers` | | `keycloak.extraVolumes` | `keycloak.extraVolumes` | | `keycloak.extraVolumeMounts` | `keycloak.extraVolumeMounts` | - -**Path changes for volume mounts:** -- Bitnami: `/opt/bitnami/keycloak/...` -- CloudPirates: `/opt/keycloak/...` +| `/opt/bitnami/keycloak/...` | `/opt/keycloak/...` | --- @@ -154,10 +295,6 @@ keycloak: httpRelativePath: /auth # NOT /auth/ ``` -The chart concatenates `httpRelativePath + /realms/master`: -- `/auth` → `/auth/realms/master` ✅ -- `/auth/` → `/auth//realms/master` ❌ - ### 2. Database Authentication Failed **Symptom**: `password authentication failed for user` @@ -218,179 +355,6 @@ keycloak: --- -## Migration Steps - -### Step 1: Backup Current Installation - -```bash -# Get the Keycloak admin password -KEYCLOAK_PASSWORD=$(kubectl get secret -keycloak -n \ - -o jsonpath="{.data.admin-password}" | base64 --decode) - -# Port forward to Keycloak -kubectl port-forward svc/-keycloak 8080:80 -n & - -# Access Admin Console and export realm: -# 1. Navigate to http://localhost:8080/auth/admin -# 2. Login with admin credentials -# 3. Go to Realm Settings → Action → Partial Export -# 4. Select all options and export to JSON - -# If using dedicated PostgreSQL, backup the database: -kubectl exec -n -- \ - pg_dump -U keycloak -d keycloak > keycloak_backup.sql -``` - -### Step 2: Update Chart.yaml - -Change the Keycloak dependency: - -```yaml -# Before (Bitnami) -dependencies: - - condition: keycloak.enabled - name: keycloak - repository: oci://registry-1.docker.io/bitnamicharts - version: 23.0.0 - -# After (CloudPirates) -dependencies: - - condition: keycloak.enabled - name: keycloak - repository: oci://registry-1.docker.io/cloudpirates - version: 0.13.6 -``` - -### Step 3: Update values.yaml - -Migrate configuration using the mapping tables above. Key changes: - -```yaml -keycloak: - # Image (CloudPirates uses official image) - image: - tag: "26.5.2" - - # Admin config - nested under keycloak.* - keycloak: - adminUser: admin - adminPassword: "your-password" - proxyHeaders: "xforwarded" # Was: proxy: edge - production: false - httpRelativePath: /auth # NO trailing slash! - - # Database - different structure - database: - type: postgres - host: "postgresql-service" - name: keycloak - existingSecret: "keycloak-db-secret" # Must have db-username, db-password keys - - postgres: - enabled: false # Use external PostgreSQL -``` - -### Step 4: Create Database Secret - -CloudPirates requires specific secret keys: - -```bash -kubectl create secret generic keycloak-db-secret -n \ - --from-literal=db-username="keycloak_user" \ - --from-literal=db-password="your_db_password" -``` - -Or via template: -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: keycloak-db-secret -type: Opaque -stringData: - db-username: "keycloak_user" - db-password: "your_db_password" -``` - -### Step 5: Update Volume Mounts (if using custom themes) - -```yaml -# Before (Bitnami) -extraVolumeMounts: - - name: themes - mountPath: /opt/bitnami/keycloak/themes/custom - -# After (CloudPirates) -extraVolumeMounts: - - name: themes - mountPath: /opt/keycloak/themes/custom -``` - -### Step 6: Uninstall Current Deployment - -```bash -# Uninstall current Keycloak -helm uninstall -n - -# Optional: Delete PVCs if you want a clean start -kubectl delete pvc data--keycloak-0 -n - -# Wait for pods to terminate -kubectl wait --for=delete pod/-keycloak-0 -n --timeout=120s -``` - -### Step 7: Deploy CloudPirates Keycloak - -```bash -# Update dependencies -helm dependency update - -# Install new version -helm install . -n - -# Wait for Keycloak to be ready -kubectl wait --for=condition=ready pod/-keycloak-0 -n --timeout=600s -``` - -### Step 8: Verify Migration - -```bash -# Check pod status -kubectl get pods -n - -# Check Keycloak version -kubectl logs -keycloak-0 -n | head -20 - -# Port forward and test -kubectl port-forward svc/-keycloak 8080:80 -n & - -# Verify Keycloak is responding -curl -s http://localhost:8080/auth/realms/master | jq .realm - -# Access admin console -echo "Admin Console: http://localhost:8080/auth/admin" -``` - -### Step 9: Import Realm (if needed) - -If realm was not auto-imported, use the backup from Step 1: - -```bash -# Via Admin Console: -# 1. Go to http://localhost:8080/auth/admin -# 2. Create realm → Import → Select your backup JSON - -# Or via keycloak-config-cli: -kubectl run realm-import --rm -i --restart=Never \ - --image=adorsys/keycloak-config-cli:latest-26 \ - --env="KEYCLOAK_URL=http://-keycloak" \ - --env="KEYCLOAK_USER=admin" \ - --env="KEYCLOAK_PASSWORD=" \ - -- java -jar /app/keycloak-config-cli.jar --import.files.locations=/realm.json -``` - ---- - ## Migration Checklist - [ ] Backup existing realm data (export from Admin Console) @@ -403,6 +367,7 @@ kubectl run realm-import --rm -i --restart=Never \ - [ ] Remove trailing slash from `httpRelativePath` - [ ] Run `helm dependency update` - [ ] Deploy and verify +- [ ] Test all authentication flows --- @@ -447,6 +412,9 @@ keycloak: hosts: - keycloak.example.com + service: + httpPort: 80 + extraVolumes: - name: themes emptyDir: {} @@ -454,6 +422,14 @@ keycloak: extraVolumeMounts: - name: themes mountPath: /opt/keycloak/themes/custom + + extraInitContainers: + - name: import-themes + image: your-themes-image:tag + command: ["sh", "-c", "cp -R /themes/* /dest"] + volumeMounts: + - name: themes + mountPath: /dest ``` --- From 7908d4a3f377e5b8414284633408670eaf9c54a4 Mon Sep 17 00:00:00 2001 From: mgarciaLKS Date: Wed, 25 Feb 2026 14:36:37 +0100 Subject: [PATCH 3/7] Enhance migration guide with detailed backup instructions for Keycloak and pgAdmin --- ...O_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md | 93 ++++++++++++++++--- 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md index 53465b0b..b79bca0f 100644 --- a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md +++ b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md @@ -24,26 +24,95 @@ This guide provides generic migration instructions for any project using the Bit ### Step 1: Backup Current Installation +#### 1a. Export Realm from Keycloak Admin Console + ```bash # Get the Keycloak admin password KEYCLOAK_PASSWORD=$(kubectl get secret -keycloak -n \ -o jsonpath="{.data.admin-password}" | base64 --decode) -# Port forward to Keycloak +# Port forward to Keycloak (skip if using ingress) kubectl port-forward svc/-keycloak 8080:80 -n & +``` + +1. Navigate to the Keycloak Admin Console (`http://localhost:8080/auth/admin` or your ingress URL) +2. Login with admin credentials +3. Go to **Realm Settings → Action → Partial Export** +4. Select all options and export to JSON +5. Save the JSON file (e.g., `realm-export.json`) + +#### 1b. Backup Database Using pgAdmin + +> 💡 **Tip**: If your Helm chart already deploys pgAdmin as a subchart (e.g., `pgadmin4.enabled: true`), you can use that instance directly — it already has network access to the PostgreSQL service within the cluster. +> +> Example subchart configuration: +> ```yaml +> pgadmin4: +> enabled: true +> env: +> email: admin@example.com +> password: admin-password +> ingress: +> enabled: true +> hosts: +> - host: pgadmin.example.com +> paths: +> - path: / +> pathType: Prefix +> ``` + +**Option A — pgAdmin runs inside the same cluster (recommended):** + +Since pgAdmin can resolve Kubernetes service names directly, no port-forward is needed: + +| Field | Value | +|-------|-------| +| **Host name/address** | `-postgresql` (Kubernetes service name) | +| **Port** | `5432` | +| **Maintenance database** | your Keycloak database name | +| **Username** | your Keycloak database user | +| **Password** | *(retrieve from your Kubernetes secret, see below)* | + +**Option B — pgAdmin runs outside the cluster:** + +Create a port-forward first, then connect to `localhost`: + +```bash +kubectl port-forward svc/-postgresql 5432:5432 -n & +``` -# Export realm from Admin Console: -# 1. Navigate to http://localhost:8080/auth/admin -# 2. Login with admin credentials -# 3. Go to Realm Settings → Action → Partial Export -# 4. Select all options and export to JSON -# 5. Save the JSON file +| Field | Value | +|-------|-------| +| **Host name/address** | `localhost` | +| **Port** | `5432` | +| **Maintenance database** | your Keycloak database name | +| **Username** | your Keycloak database user | +| **Password** | *(retrieve from your Kubernetes secret, see below)* | -# If using dedicated PostgreSQL, backup the database: -kubectl exec -n -- \ - pg_dump -U keycloak -d keycloak > keycloak_backup.sql +To retrieve the database password from your Kubernetes secret: +```bash +kubectl get secret -n -o jsonpath='{.data.}' | base64 -d ``` +**Register the server and create the backup:** + +1. Open pgAdmin and log in +2. Right-click **Servers** → **Register** → **Server...** +3. In the **General** tab, set a name (e.g., `Keycloak PostgreSQL`) +4. In the **Connection** tab, fill in the values from the table above +5. Click **Save** +6. In the browser tree, expand **Servers → Keycloak PostgreSQL → Databases** +7. Right-click your database → **Backup...** +8. Configure the backup: + - **Filename**: `keycloak_backup` (pgAdmin will add the extension) + - **Format**: `Custom` (recommended, supports selective restore) or `Plain` (SQL text) + - **Encoding**: `UTF8` +9. *(Optional)* In the **Data/Objects** tab: + - Enable **Include CREATE DATABASE statement** for a full restore option + - Enable **Use Column Inserts** for maximum compatibility +10. Click **Backup** +11. Verify the backup completed successfully in the pgAdmin notifications panel (bell icon, bottom-right) + ### Step 2: Update Chart.yaml Change the Keycloak dependency: @@ -358,7 +427,7 @@ keycloak: ## Migration Checklist - [ ] Backup existing realm data (export from Admin Console) -- [ ] Backup database (if applicable) +- [ ] Backup database using pgAdmin (or equivalent tool) - [ ] Update `Chart.yaml` dependency - [ ] Update `values.yaml` configuration structure - [ ] Create/update database secret with `db-username`/`db-password` keys @@ -439,4 +508,4 @@ keycloak: This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). - SPDX-License-Identifier: CC-BY-4.0 -- SPDX-FileCopyrightText: 2025 Contributors to the Eclipse Foundation +- SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation From d49728c356436fe23c6ad17dad2c558577300bac Mon Sep 17 00:00:00 2001 From: Mikel Garcia Date: Fri, 6 Mar 2026 10:33:45 +0100 Subject: [PATCH 4/7] Update SPDX copyright information in migration guide --- ...NERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md index b79bca0f..a0e9aaf6 100644 --- a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md +++ b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md @@ -507,5 +507,10 @@ keycloak: This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). +- SPDX-License-Identifier: CC-BY-4.0 +- SPDX-FileCopyrightText: 2025, 2026 Contributors to the Eclipse Foundation +- SPDX-FileCopyrightText: 2025, 2026 Catena-X Automotive Network e.V. +- SPDX-FileCopyrightText: 2025, 2026 LKS Next + - SPDX-License-Identifier: CC-BY-4.0 - SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation From 85617d29c7cdb9982930848e9614f0b5327c5ce6 Mon Sep 17 00:00:00 2001 From: Mikel Garcia Date: Fri, 6 Mar 2026 10:34:09 +0100 Subject: [PATCH 5/7] Update migration guide with license and copyright Added licensing information and copyright notices. --- migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md b/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md index 3afabfe3..35b65337 100644 --- a/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md +++ b/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md @@ -48,6 +48,15 @@ Set these variables according to your deployment **before starting**: export NAMESPACE="your-namespace" # e.g., "production", "staging" export RELEASE_NAME="your-release" # e.g., "my-app", "backend-service" export POSTGRES_POD="${RELEASE_NAME}-postgresql-0" # StatefulSet pod name + +## NOTICE + +This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). + +- SPDX-License-Identifier: CC-BY-4.0 +- SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +- SPDX-FileCopyrightText: 2026 Catena-X Automotive Network e.V. +- SPDX-FileCopyrightText: 2026 LKS Next export PG_USER="postgres" # PostgreSQL admin user export PG_DATABASE="your-database" # Main database name export SECRET_NAME="your-postgres-secret" # Secret containing passwords From 4f866002495d934781d95605e1224d6f2be50801 Mon Sep 17 00:00:00 2001 From: Mikel Garcia Date: Fri, 6 Mar 2026 10:34:27 +0100 Subject: [PATCH 6/7] Update SPDX copyright years in migration guide --- ...ERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md index a0e9aaf6..88494ae4 100644 --- a/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md +++ b/migration-guides/GENERIC_BITNAMI_TO_CLOUDPIRATES_KEYCLOAK_MIGRATION_GUIDE.md @@ -508,9 +508,9 @@ keycloak: This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). - SPDX-License-Identifier: CC-BY-4.0 -- SPDX-FileCopyrightText: 2025, 2026 Contributors to the Eclipse Foundation -- SPDX-FileCopyrightText: 2025, 2026 Catena-X Automotive Network e.V. -- SPDX-FileCopyrightText: 2025, 2026 LKS Next +- SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +- SPDX-FileCopyrightText: 2026 Catena-X Automotive Network e.V. +- SPDX-FileCopyrightText: 2026 LKS Next - SPDX-License-Identifier: CC-BY-4.0 - SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation From 5c4ffcc2f0deee62d3f5fcf673599aa23208e623 Mon Sep 17 00:00:00 2001 From: Mikel Garcia Date: Fri, 6 Mar 2026 10:36:10 +0100 Subject: [PATCH 7/7] Clean up licensing information in migration guide Removed licensing information and notices from the migration guide. --- .../GENERIC_POSTGRESQL_MIGRATION_GUIDE.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md b/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md index 35b65337..1054b3e0 100644 --- a/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md +++ b/migration-guides/GENERIC_POSTGRESQL_MIGRATION_GUIDE.md @@ -48,15 +48,6 @@ Set these variables according to your deployment **before starting**: export NAMESPACE="your-namespace" # e.g., "production", "staging" export RELEASE_NAME="your-release" # e.g., "my-app", "backend-service" export POSTGRES_POD="${RELEASE_NAME}-postgresql-0" # StatefulSet pod name - -## NOTICE - -This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). - -- SPDX-License-Identifier: CC-BY-4.0 -- SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation -- SPDX-FileCopyrightText: 2026 Catena-X Automotive Network e.V. -- SPDX-FileCopyrightText: 2026 LKS Next export PG_USER="postgres" # PostgreSQL admin user export PG_DATABASE="your-database" # Main database name export SECRET_NAME="your-postgres-secret" # Secret containing passwords @@ -521,5 +512,6 @@ postgresql: # Note: uses alias in Chart.yaml This work is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). - SPDX-License-Identifier: CC-BY-4.0 -- SPDX-FileCopyrightText: 2025, 2026 Contributors to the Eclipse Foundation -- Source URL: https://github.com/eclipse-tractusx +- SPDX-FileCopyrightText: 2026 Contributors to the Eclipse Foundation +- SPDX-FileCopyrightText: 2026 Catena-X Automotive Network e.V. +- SPDX-FileCopyrightText: 2026 LKS Next