keycloak-clustered
keycloak-clustered extends Keycloak Official Image so that we can easily run a Keycloak cluster
500K+
Keycloak-Clustered extends quay.io/keycloak/keycloak official Keycloak Docker image by adding JDBC_PING discovery protocol
On ivangfr.github.io, I have compiled my Proof-of-Concepts (PoCs) and articles. You can easily search for the technology you are interested in by using the filter. Who knows, perhaps I have already implemented a PoC or written an article about what you are looking for.
Since the release of version 26.1.0, the Keycloak default transport stack for cluster discovery has been switched to JDBC-PING, simplifying cluster setup and improving cloud compatibility.
In the articles below, I explain how to set up a local Keycloak cluster for development or production with three nodes using Docker Compose.
26.0.8, latest (Dockerfile)26.0.7 (Dockerfile)26.0.6 (Dockerfile)26.0.5 (Dockerfile)26.0.4 (Dockerfile)26.0.2 (Dockerfile)26.0.1 (Dockerfile)26.0.0 (Dockerfile)25.0.6 (Dockerfile)25.0.5 (Dockerfile)25.0.4 (Dockerfile)25.0.2 (Dockerfile)25.0.1 (Dockerfile)25.0.0 (Dockerfile)Ivan Franchin (LinkedIn) (Github) (Medium) (X)
Please, refer to the official Keycloak documentation at https://www.keycloak.org/server/all-config
Navigate into one of the version folders and run the following command
docker build -t ivanfranchin/keycloak-clustered:latest .
Open two different browsers, for instance Chrome and Safari or Chrome and Incognito Chrome.
In one access http://localhost:8080 and, in another, http://localhost:8081
Login with the following credentials
username: admin
password: admin
Once logged in
Sessions present on the menu on the left;admin has two sessions.Open a terminal and create a Docker network
docker network create keycloak-net
Run MySQL Docker container
docker run --rm --name mysql -p 3306:3306 \
-e MYSQL_DATABASE=keycloak \
-e MYSQL_USER=keycloak \
-e MYSQL_PASSWORD=password \
-e MYSQL_ROOT_PASSWORD=root_password \
--network keycloak-net \
mysql:9.1.0
Open another terminal and run keycloak-clustered-1 Docker container
docker run --rm --name keycloak-clustered-1 -p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=mysql \
-e KC_DB_URL_HOST=mysql \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-1 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
Finally, open another terminal and run keycloak-clustered-2 Docker container
docker run --rm --name keycloak-clustered-2 -p 8081:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=mysql \
-e KC_DB_URL_HOST=mysql \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-2 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
In order to test it, have a look at How to check if keycloak-clustered instances are sharing user sessions
Access MySQL monitor terminal inside mysql Docker container
docker exec -it -e MYSQL_PWD=password mysql mysql -ukeycloak --database keycloak
List tables
mysql> show tables;
Select entries in JGROUPSPING table
mysql> SELECT * FROM JGROUPSPING;
To exit MySQL monitor terminal type exit
To stop keycloak-clustered-1 and keycloak-clustered-2 Docker containers, press Ctrl+C in their terminals;
To stop mysql Docker container, press Ctrl+\ in its terminal;
To remove Docker network, run in a terminal
docker network rm keycloak-net
Open a terminal and create a Docker network
docker network create keycloak-net
Run MariaDB Docker container
docker run --rm --name mariadb -p 3306:3306 \
-e MARIADB_DATABASE=keycloak \
-e MARIADB_USER=keycloak \
-e MARIADB_PASSWORD=password \
-e MARIADB_ROOT_PASSWORD=root_password \
--network keycloak-net \
mariadb:10.11.10
Open another terminal and run keycloak-clustered-1 Docker container
docker run --rm --name keycloak-clustered-1 -p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=mariadb \
-e KC_DB_URL_HOST=mariadb \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-1 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
Finally, open another terminal and run keycloak-clustered-2 Docker container
docker run --rm --name keycloak-clustered-2 -p 8081:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=mariadb \
-e KC_DB_URL_HOST=mariadb \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-2 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
In order to test it, have a look at How to check if keycloak-clustered instances are sharing user sessions
Access MariaDB monitor terminal inside mariadb Docker container
docker exec -it mariadb mariadb -ukeycloak -ppassword --database keycloak
List tables
MariaDB [keycloak]> show tables;
Select entries in JGROUPSPING table
MariaDB [keycloak]> SELECT * FROM JGROUPSPING;
To exit MariaDB monitor terminal type `exit
To stop keycloak-clustered-1 and keycloak-clustered-2 Docker containers, press Ctrl+C in their terminals;
To stop mariadb Docker container, press Ctrl+\ in its terminal;
To remove Docker network, run in a terminal
docker network rm keycloak-net
Open a terminal and create a Docker network
docker network create keycloak-net
Run Postgres Docker container
docker run --rm --name postgres -p 5432:5432 \
-e POSTGRES_DB=keycloak \
-e POSTGRES_USER=keycloak \
-e POSTGRES_PASSWORD=password \
--network keycloak-net \
postgres:17.2
Open another terminal and run keycloak-clustered-1 Docker container
docker run --rm --name keycloak-clustered-1 -p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=postgres \
-e KC_DB_URL_HOST=postgres \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_SCHEMA=myschema \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-1 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
Finally, open another terminal and run keycloak-clustered-2 Docker container
docker run --rm --name keycloak-clustered-2 -p 8081:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=postgres \
-e KC_DB_URL_HOST=postgres \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_SCHEMA=myschema \
-e KC_DB_USERNAME=keycloak \
-e KC_DB_PASSWORD=password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-2 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
In order to test it, have a look at How to check if keycloak-clustered instances are sharing user sessions
Access psql terminal inside postgres Docker container
docker exec -it postgres psql -U keycloak
List tables in myschema schema
keycloak=# \dt myschema.*
Select entries in JGROUPSPING table
keycloak=# SELECT * FROM myschema.JGROUPSPING;
To exit psql terminal type \q
To stop postgres, keycloak-clustered-1 and keycloak-clustered-2 Docker containers, press Ctrl+C in their terminals;
To remove Docker network, run in a terminal
docker network rm keycloak-net
Warning: It is not working! See Issues section
Open a terminal and create a Docker network
docker network create keycloak-net
Run Microsoft SQL Server Docker container
docker run --rm --name mssql -p 1433:1433 \
-e ACCEPT_EULA=Y \
-e MSSQL_SA_PASSWORD=my_Password \
--network keycloak-net \
mcr.microsoft.com/mssql/server:2022-CU11-ubuntu-22.04
Open another terminal and run the following command to create keycloak database
docker exec -i mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P my_Password -Q 'CREATE DATABASE keycloak'
In a terminal, run keycloak-clustered-1 Docker container
docker run --rm --name keycloak-clustered-1 -p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=mssql \
-e KC_DB_URL_HOST=mssql \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_URL_PROPERTIES=";trustServerCertificate=false;encrypt=false" \
-e KC_DB_USERNAME=SA \
-e KC_DB_PASSWORD=my_Password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-1 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
Finally, open another terminal and run keycloak-clustered-2 Docker container
docker run --rm --name keycloak-clustered-2 -p 8081:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
-e KC_DB=mssql \
-e KC_DB_URL_HOST=mssql \
-e KC_DB_URL_DATABASE=keycloak \
-e KC_DB_URL_PROPERTIES=";trustServerCertificate=false;encrypt=false" \
-e KC_DB_USERNAME=SA \
-e KC_DB_PASSWORD=my_Password \
-e KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG \
-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-2 \
--network keycloak-net \
ivanfranchin/keycloak-clustered:latest start-dev
In order to test it, have a look at How to check if keycloak-clustered instances are sharing user sessions
Access sqlcmd terminal inside mssql Docker container
docker exec -it mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P my_Password
Select entries in JGROUPSPING table
1> select * from keycloak.myschema.JGROUPSPING
2> go
To exit sqlcmd terminal type exit or press Ctrl+C
To stop keycloak-clustered-1 and keycloak-clustered-2 Docker containers, press Ctrl+C in their terminals;
To remove Docker network, run in a terminal
docker network rm keycloak-net
VirtualBox and Vagrant
Open a terminal and make sure you are in keycloak-clustered root folder
You can edit Vagrantfile and set the database and/or the discovery protocol to be used
Start the virtual machines by running the command below
vagrant up
Mac Users
If you have an error like the one below
The IP address configured for the host-only network is not within the allowed ranges. Please update the address used to be within the allowed ranges and run the command again. Address: 10.0.0.1 Ranges: 123.456.78.0/21 Valid ranges can be modified in the /etc/vbox/networks.conf file. For more information including valid format see: https://www.virtualbox.org/manual/ch06.html#network_hostonlyCreate a new file at
/etc/vbox/networks.confon your Mac with content* 10.0.0.0/8 123.456.78.0/21 * 2001::/64
Wait a bit until the virtual machines get started. It will take some time.
Once the execution of the command vagrant up finishes, we can check the state of all active Vagrant environments
vagrant status
Check keycloak-clustered docker logs in keycloak1 virtual machine
vagrant ssh keycloak1
vagrant@vagrant:~$ docker logs keycloak-clustered -f
Note: To get out of the logging view press
Ctrl+Cand to exit the virtual machine typeexit
Check keycloak-clustered docker logs in keycloak2 virtual machine
vagrant ssh keycloak2
vagrant@vagrant:~$ docker logs keycloak-clustered -f
Note: To get out of the logging view press
Ctrl+Cand to exit the virtual machine typeexit
Check databases if you are using JDBC_PING
vagrant ssh databases
Note: To exit the virtual machine type
exit
MySQL
vagrant@vagrant:~$ docker exec -it -e MYSQL_PWD=password mysql mysql -ukeycloak --database keycloak
mysql> show tables;
mysql> SELECT * FROM JGROUPSPING;
Note: To exit type
exit
MariaDB
vagrant@vagrant:~$ docker exec -it mariadb mysql -ukeycloak -ppassword --database keycloak
MariaDB [keycloak]> show tables;
MariaDB [keycloak]> SELECT * FROM JGROUPSPING;
Note: To exit type
exit
Postgres
vagrant@vagrant:~$ docker exec -it postgres psql -U keycloak
keycloak=# \dt *.*
-- `public` schema
keycloak=# SELECT * FROM JGROUPSPING;
-- in case the schema `myschema` was set
keycloak=# SELECT * FROM myschema.JGROUPSPING;
Note: To exit type
\q
In order to test it, have a look at How to check if keycloak-clustered instances are sharing user sessions
Edit Vagrantfile by setting to DB_VENDOR variable the database to be used
Reload Keycloak virtual machines by running
vagrant reload keycloak1 keycloak2 --provision
Suspending the virtual machines will stop them and save their current running state. For it run
vagrant suspend
To bring the virtual machines back up run
vagrant up
Halting the virtual machines will gracefully shut down the guest operating system and power down the guest machine
vagrant halt
It preserves the contents of disk and allows to start it again by running
vagrant up
Destroying the virtual machine will remove all traces of the guest machine from your system. It'll stop the guest machine, power it down, and reclaim its disk space and RAM.
vagrant destroy -f
For a complete clean up, you can remove Vagrant box used in this section
vagrant box remove hashicorp/bionic64
Content type
Image
Digest
sha256:fcbeaf83f…
Size
230.1 MB
Last updated
over 1 year ago
docker pull ivanfranchin/keycloak-clustered