rhondamuse.com

Setting Up a Keycloak Cluster with Docker Compose and JDBC-PING

Written on

In this guide, we will walk you through the process of configuring a Keycloak cluster locally with three instances, enabling distributed caching. This setup is particularly useful for developers who want to secure their applications using Keycloak and test the entire solution in a controlled local environment.

Keycloak is an open-source Identity and Access Management (IAM) solution that provides comprehensive user identity management, authentication, and authorization capabilities for applications.

Each Keycloak instance will run in its own Docker container, utilizing a MariaDB database for data storage. To streamline the setup and configuration of these containers, we will make use of Docker Compose. This tool simplifies the management of multi-container Docker applications through a YAML-based syntax that defines and configures the necessary containers, networks, and volumes for your application.

The distributed cache functionality in Keycloak is built on Infinispan, an open-source, distributed, in-memory key-value data store, which is designed for high scalability, availability, and fault tolerance.

When running Keycloak in development mode with the “start-dev” command, distributed caches are disabled. Conversely, in production mode with the “start” command, caching is activated, allowing automatic discovery of Keycloak instances on the network. By default, these caches employ a UDP transport stack for IP multicast-based instance discovery.

In this article, we will deviate from the default configuration by using JDBC-PING instead. JDBC-PING enables distributed caching in Keycloak by utilizing a JDBC-compatible database for storing and sharing cached data among multiple instances. For this purpose, we will use the MariaDB database to facilitate the JDBC-PING discovery protocol.

Since the official Keycloak Docker image does not directly support JDBC-PING, we will employ a custom Docker image named keycloak-clustered. This maintained image is based on the official Keycloak Docker image and includes a modified Infinispan configuration file to support the JDBC-PING discovery protocol. You can access the code for this custom image in the keycloak-clustered GitHub repository.

For a more in-depth understanding of the modifications made to the Infinispan configuration file for JDBC-PING support, I encourage you to read the supplementary article, which offers detailed insights on the subject.

Let’s get started!

Project Diagram

The visual representation of our desired project outcome.

Additional Readings

  • Keycloak Cluster Setup with Vagrant, Virtual Machines, and JDBC-PING for Distributed Caching

    Step-by-step guide on how to use Vagrant to deploy and manage a cluster of three Keycloak instances.

    (source: medium.com)

  • Keycloak Cluster Setup with Docker Compose and UDP for Distributed Caching

    Step-by-step guide on how to use Docker Compose to start a cluster of three Keycloak Docker containers using UDP for distributed caching.

    (source: medium.com)

  • Keycloak Cluster Setup with UDP for Distributed Caching in Minikube (Kubernetes)

    Step-by-step guide on how to start a cluster of three Keycloak instances using UDP for distributed caching in Minikube.

    (source: medium.com)

Prerequisites

To follow this guide, please ensure that you have Docker Desktop installed on your machine. You can find installation instructions for Mac, Windows, and Linux on the Docker Docs website.

Creating the Docker Compose File

Open your preferred text editor and create a file named docker-compose.yml with the following content:

version: '3.8'

services:

mariadb:

image: mariadb:10.11.4

container_name: mariadb

ports:

  • "3306:3306"

environment:

  • MARIADB_DATABASE=keycloak
  • MARIADB_USER=keycloak
  • MARIADB_PASSWORD=password
  • MARIADB_ROOT_PASSWORD=root_password

keycloak-clustered-1:

image: ivanfranchin/keycloak-clustered:latest

container_name: keycloak-clustered-1

environment:

  • KEYCLOAK_ADMIN=admin
  • KEYCLOAK_ADMIN_PASSWORD=admin
  • KC_DB=mariadb
  • KC_DB_URL_HOST=mariadb
  • KC_DB_URL_DATABASE=keycloak
  • KC_DB_USERNAME=keycloak
  • KC_DB_PASSWORD=password
  • KC_HEALTH_ENABLED=true
  • KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG
  • JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-1

ports:

  • "8080:8080"

command: start-dev

depends_on:

  • mariadb

keycloak-clustered-2:

image: ivanfranchin/keycloak-clustered:latest

container_name: keycloak-clustered-2

environment:

  • KEYCLOAK_ADMIN=admin
  • KEYCLOAK_ADMIN_PASSWORD=admin
  • KC_DB=mariadb
  • KC_DB_URL_HOST=mariadb
  • KC_DB_URL_DATABASE=keycloak
  • KC_DB_USERNAME=keycloak
  • KC_DB_PASSWORD=password
  • KC_HEALTH_ENABLED=true
  • KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG
  • JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-2

ports:

  • "8081:8080"

command: start-dev

depends_on:

  • mariadb

keycloak-clustered-3:

image: ivanfranchin/keycloak-clustered:latest

container_name: keycloak-clustered-3

environment:

  • KEYCLOAK_ADMIN=admin
  • KEYCLOAK_ADMIN_PASSWORD=admin
  • KC_DB=mariadb
  • KC_DB_URL_HOST=mariadb
  • KC_DB_URL_DATABASE=keycloak
  • KC_DB_USERNAME=keycloak
  • KC_DB_PASSWORD=password
  • KC_HEALTH_ENABLED=true
  • KC_LOG_LEVEL=INFO,org.infinispan:DEBUG,org.jgroups:DEBUG
  • JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-clustered-3

ports:

  • "8082:8080"

command: start-dev

depends_on:

  • mariadb

Save the docker-compose.yml file in your preferred directory.

Starting the Cluster

Navigate to the folder containing your docker-compose.yml file and run the following command:

docker compose up -d

Executing this command will initiate the following processes:

  1. Docker Compose reads the configuration file (docker-compose.yml).
  2. Docker pulls the necessary container images if they are not already available.
  3. Containers for each service are created and started.
  4. The containers run in the background (detached mode).
  5. Networks are connected and ports are mapped as specified.
  6. Dependencies between services are managed automatically.
  7. You can interact with the services once they are running.

Demonstration

To verify that our Keycloak cluster is functioning correctly, follow these steps:

  1. Open three different browsers (e.g., Chrome, Safari, and Firefox) or use different profiles (e.g., Chrome, Incognito Chrome, and Firefox).
  2. Access the following URLs:
  3. Log in to Keycloak using “admin” as both the username and password.
  4. In one of the browsers, click on “Sessions” in the left-side menu. You should see that the “admin” user has three active sessions.
  5. Sign out of Keycloak in one of the browsers.
  6. Check the session count for the “admin” user again; it should now show two active sessions.

By following these steps, you can assess the functionality of the Keycloak cluster and observe how session management operates for the “admin” user.

Troubleshooting

Check Keycloak Logs You can inspect the logs of the keycloak-clustered-1 container using the following command:

docker logs keycloak-clustered-1

Check JGROUPSPING Table To access the MariaDB Docker container’s terminal (MariaDB Monitor), run the following command:

docker exec -it mariadb mariadb -ukeycloak -ppassword --database keycloak

Within the MariaDB Monitor, execute the following SELECT command to view information about the Keycloak instances in the cluster:

SELECT * FROM JGROUPSPING;

This query should yield results similar to the following:

To exit the MariaDB Monitor, simply type “exit” and hit Enter.

Shutting Down the Cluster

Ensure that you are in the directory where you saved the docker-compose.yml file, and execute the following command:

docker compose down -v

Conclusion

In this tutorial, we demonstrated how to set up a Keycloak cluster with three instances for distributed caching. By using Docker and Docker Compose, we simplified the configuration of Keycloak instances across separate containers. The cluster leverages Infinispan for distributed caching, ensuring scalability and fault tolerance. For this demonstration, we employed a custom Keycloak Clustered Docker image and utilized the JDBC-PING discovery protocol.

Support and Engagement

If you found this article helpful and would like to support my work, consider taking the following actions:

  • Engage by clapping, highlighting, and replying to my story. I’m here to answer any questions you may have.
  • Share this story on social media.
  • Follow me on: Medium | LinkedIn | Twitter.
  • Subscribe to my newsletter to stay updated with my latest posts.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

# Exploring the Challenges of Artificial Gravity on the Enterprise

An exploration of the scientific challenges behind artificial gravity as depicted in Star Trek's Enterprise and the realities of space travel.

Phantom Hacker Scams: FBI's Essential Guide to Safeguarding Your Finances

Discover how to protect yourself from Phantom Hacker scams as outlined by the FBI, highlighting essential steps to secure your finances.

Groundbreaking 20-Minute Whale Conversation: A Scientific Milestone

Scientists engage in a historic 20-minute conversation with a humpback whale named Twain, merging marine biology and the search for extraterrestrial intelligence.

Embrace the Moon's Wisdom: A Letter from Moonbae

Discover how the phases of the moon influence our lives and the insights shared by Moon Bae in this heartfelt letter.

How to Break Into Show Business: A Comprehensive Guide

Discover effective strategies for entering the show business industry and achieving your dreams.

Maximizing Startup Potential Through Digital Advertising

Discover how digital advertising can effectively enhance your startup's growth and save you money in the long run.

Two Powerful Techniques for Soothe a Crying Baby: A Personal Tale

Discover two effective methods to soothe a crying baby through personal experiences and heartfelt moments.

Reflecting on Four Years After COVID-19: Lessons Learned

A reflective piece on the changes brought by COVID-19, emphasizing community, personal growth, and the importance of connection.