Upgrading Keycloak can feel like a high-stakes operation, but the real trick is understanding the subtle state transitions that make a smooth migration possible.
Let’s see Keycloak in action during an upgrade. Imagine we have a running Keycloak instance (v18.0.0) with a couple of clients, my-app and another-app, and a user, alice.
# On Keycloak server, check current version
curl -s "http://localhost:8080/realms/master/serverinfo" | jq .version
# Expected output: "18.0.0"
# Client details (simplified for illustration)
curl -s -X GET "http://localhost:8080/admin/realms/myrealm/clients?clientId=my-app" \
-H "Authorization: Bearer <admin_token>" | jq '.[0].clientId'
# Expected output: "my-app"
# User details
curl -s -X GET "http://localhost:8080/admin/realms/myrealm/users?username=alice" \
-H "Authorization: Bearer <admin_token>" | jq '.[0].username'
# Expected output: "alice"
Now, we’re going to upgrade to v19.0.1. The process typically involves stopping the old server, replacing the binaries, and starting the new one. Keycloak handles database schema migrations automatically on startup if they are needed.
# 1. Stop the old Keycloak instance (v18.0.0)
# (Assuming it's running via systemd or similar)
sudo systemctl stop keycloak
# 2. Backup Keycloak data (essential!)
# This includes the database and potentially standalone/conf directories.
# Example: pg_dump -U keycloak_user keycloak_db > keycloak_db_backup.sql
# cp -r /opt/keycloak/standalone /opt/keycloak/standalone_backup
# 3. Replace Keycloak binaries with the new version (v19.0.1)
# Download and extract the new distribution to the same location.
# Example: rm -rf /opt/keycloak/* && tar -xzf keycloak-19.0.1.tar.gz -C /opt/keycloak --strip-components=1
# 4. Start the new Keycloak instance (v19.0.1)
sudo systemctl start keycloak
# 5. Verify the new version
curl -s "http://localhost:8080/realms/master/serverinfo" | jq .version
# Expected output: "19.0.1"
# Verify clients and users are still accessible
curl -s -X GET "http://localhost:8080/admin/realms/myrealm/clients?clientId=my-app" \
-H "Authorization: Bearer <admin_token>" | jq '.[0].clientId'
# Expected output: "my-app"
curl -s -X GET "http://localhost:8080/admin/realms/myrealm/users?username=alice" \
-H "Authorization: Bearer <admin_token>" | jq '.[0].username'
# Expected output: "alice"
The mental model for Keycloak upgrades hinges on its database schema migration strategy. Keycloak uses Liquibase under the hood. When you start a new version, it checks its current schema version against the version defined in its changelogs. If they don’t match, Liquibase attempts to apply the necessary SQL statements to bring the database up to the required schema for the new version. This is why a database backup is paramount – a failed migration can leave your database in an inconsistent state.
The key levers you control are:
- Database choice and configuration: Ensure your database (PostgreSQL, MySQL, etc.) is supported by the new Keycloak version and that Keycloak has the correct credentials and permissions to modify its schema.
- Keycloak distribution: The
standalone.shordomain.shscripts are responsible for initiating the startup and migration process. - Environment variables/Configuration files: Settings related to database connections (
KC_DB_URL,KC_DB_USERNAME,KC_DB_PASSWORD) are critical for the migration to succeed. - Backup and Restore strategy: Having a robust backup of your database and Keycloak configuration directories (
standalone/configuration,domain/configuration) is your safety net.
The upgrade process itself is largely automated by Keycloak’s startup scripts and Liquibase. The complexity lies in preparing for it: ensuring compatibility, having proper backups, and understanding how to roll back if necessary. Keycloak also has a "migration" mode, usually set via KC_MIGRATION_PHASE=import or similar in older versions, which you might use for specific scenarios like migrating from a standalone setup to a clustered one or to a different database type, but for typical version-to-version upgrades, the automatic schema migration on startup is the standard path.
The next logical step after a successful upgrade is to explore the new features introduced in the version you migrated to, such as advanced features in the new Admin Console or changes in the token endpoint behavior.