DEV Community

Ed Legaspi
Ed Legaspi

Posted on • Edited on

How to Setup Keycloak With MySQL Database using CLI in Docker

1. Introduction

Keycloak is one of the most popular open-source Identity and Access Management platforms backed by RedHat. It is known for its flexibility and extensibility, making it a top candidate in the enterprise world, where there are complicated use cases for user authentication and authorization use cases. For example, multiple applications must support multi-tenant and n-reseller levels with a single login.

1.1 Prerequisites

Knowledge of the following is required.

  • Keycloak
  • Docker
  • MySQL

2. ct-keycloak-iam

ct-keycloak-iam is a project I developed to deliver a custom Keycloak server in a docker container. It includes a default realm, custom themes, database connection (MySQL), and custom SPIs (required sponsorship).

It contains CLI scripts that will download the Keycloak server and install a MySQL data source.

The project is available at https://github.com/czetsuya/ct-keycloak-iam.

Folders/files that we will use.

keycloak-docker-assembly

  • docker
    • Dockerfile - builds a custom Keycloak container
    • docker-compose-dev.yml - builds and runs the custom Keycloak container and MySQL.
  • src/main/resources
    • build
      • cli/database/mysql
      • set-database.cli - a set of instructions to create an entry of MySQL data source and driver in your Keycloak configuration. Note that it uses the environment variables defined in your docker-compose file.
      • build-keycloak.sh
    • modules/databases/mysql
      • module.xml - MySQL module file needed by Keycloak. Make sure that the version matches the one defined in the Dockerfile (instead, you changed it)

3. Docker Compose

Instead of manually creating a MySQL database, users, and permissions, we will use a MySQL docker image to do the job.

We need to define the MySQL connection settings as environment variables.

version: '3' services: keycloak-db: image: mysql:8.0 ports: - 33066:3306 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: keycloak MYSQL_USER: keycloak MYSQL_PASSWORD: keycloak command: mysqld --sql_mode="" ct-keycloak-iam: depends_on: - keycloak-db build: context: ../ dockerfile: docker/Dockerfile ports: - 8888:8888 - 8080:8080 - 8443:8443 - 9990:9990 environment: DB_ADDR: keycloak-db DB_PORT: 3306 DB_DATABASE: keycloak DB_USER: keycloak DB_PASSWORD: keycloak DB_JDBC_PARAMS: useSSL=false&allowPublicKeyRetrieval=true KEYCLOAK_IMPORT: /opt/jboss/keycloak_install_stage/realms/ct-realm-dev.json KEYCLOAK_USER: keycloak.admin KEYCLOAK_PASSWORD: keycloak.admin KC_HOSTNAME_STRICT: false DEBUG_PORT: 8888 PROXY_ADDRESS_FORWARDING: 'true' 
Enter fullscreen mode Exit fullscreen mode

Make sure that the DB_XXX parameter values in the ct-keycloak-iam container match MySQL's.

4. Configure the MySQL Driver and Module

This is already done by the build-keycloak.sh, a script that copies the MySQL driver and module.xml file to the extracted Keycloak server inside the Docker container.

Here's our MySQL module file.

<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.mysql.jdbc"> <resources> <resource-root path="mysql-connector-java-8.0.29.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> </dependencies> </module> 
Enter fullscreen mode Exit fullscreen mode

5. Add the MySQL Datasource and Driver Configuration in Keycloak

This is handled by the set-database.cli script, which installs the data source and driver configuration by using the values from the environment variables such as database URL, username, password, and JDBC params.

/subsystem=datasources/data-source=KeycloakDS: remove() /subsystem=datasources/data-source=KeycloakDS: add(jndi-name=java:jboss/datasources/KeycloakDS,enabled=true,use-java-context=true,use-ccm=true, connection-url=jdbc:mysql://${env.DB_ADDR:mysql}:${env.DB_PORT:3306}/${env.DB_DATABASE:keycloak}${env.DB_JDBC_PARAMS:}, driver-name=mysql) /subsystem=datasources/data-source=KeycloakDS: write-attribute(name=user-name, value=${env.DB_USER:keycloak}) /subsystem=datasources/data-source=KeycloakDS: write-attribute(name=password, value=${env.DB_PASSWORD:password}) /subsystem=datasources/data-source=KeycloakDS: write-attribute(name=check-valid-connection-sql, value="SELECT 1") /subsystem=datasources/data-source=KeycloakDS: write-attribute(name=background-validation, value=true) /subsystem=datasources/data-source=KeycloakDS: write-attribute(name=background-validation-millis, value=60000) /subsystem=datasources/data-source=KeycloakDS: write-attribute(name=flush-strategy, value=IdleConnections) /subsystem=datasources/jdbc-driver=mysql:add(driver-name=mysql, driver-module-name=com.mysql.jdbc,driver-xa-datasource-class-name=com.mysql.cj.jdbc.MysqlXADataSource) 
Enter fullscreen mode Exit fullscreen mode

6. Running the Project

If you're familiar with docker-compose, you know that it's our entry point to our custom Keycloak server.

Before running it, comment on the line that imports the SPIs, or become my sponsor in GitHub so that you can gain access to those restricted projects.

docker-compose -f ./keycloak-docker-assembly/docker/docker-compose-dev.yml up --build 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)