Using MySQL as Database for Keycloak with Docker

  • Home
  • -
  • Blog
  • -
  • Post
  • -
  • KeycloakMysqlDockerCompose
2022 . Jan . 17 / Programming

Keycloak and MySQL

Using Keycloak to handle users has been nice for me so far, but I'm not a fan of the default way to backup (import/export) all our users info (and basically all the Keycloak configuration).

So, having MySQL as the Keycloak Database makes the backups easier and not only that, we can use Workbench to explore it.

Docker Compose

The next docker-compose file gives us the simple way to integrate both services. They are in the same network, MySQL has its own volume and Keycloak container starts after the MySQL one (though it does not necessarily waits for MySQL to be started, see: Control startup and shutdown order in Compose).

For the full Environment variables explanation visit the official Docker Hub of MySQL and Keycloak.

compose.yml
version: '3.9'

services:

  mysql-kc:
    image: mysql:8.0.27
    ports:
      - 3366:3306
    restart: unless-stopped
    environment:
      # The user, password and database that Keycloak
      # is going to create and use
      MYSQL_USER: keycloak_user
      MYSQL_PASSWORD: keycloak_password
      MYSQL_DATABASE: keycloak_db
      # Self-Explanatory
      MYSQL_ROOT_PASSWORD: root_password
    volumes:
      - keycloak-and-mysql-volume:/var/lib/mysql
    networks:
      - keycloak-and-mysql-network

  keycloak-w:
    image: jboss/keycloak:16.1.0
    ports:
      - 8181:8080
    restart: unless-stopped
    environment:
      # User and password for the Administration Console
      KEYCLOAK_USER: admin_user
      KEYCLOAK_PASSWORD: admin_password
      DB_VENDOR: mysql
      DB_ADDR: mysql-kc
      DB_PORT: 3306
      # Same values as the mysql-kc service
      DB_USER: keycloak_user
      DB_PASSWORD: keycloak_password
      DB_DATABASE: keycloak_db
    depends_on:
      - mysql-kc
    networks:
      - keycloak-and-mysql-network

networks:
  keycloak-and-mysql-network:

volumes:
  keycloak-and-mysql-volume:

And we run it with:

docker-compose -f compose.yml up -d

Import/Export Keycloak Database

Now that Keycloak is running, we can use MySQL Workbench to Export keycloak_db. Just go to Administration > Data Export and basically select everything to export.

To import it back, using Workbench again, go to Administration > Data Import/Restore. Or, if you want to use a new instance of a MySQL container on Docker, you can add a volume to the MySQL service with the initial Keycloak database (exported previously) this way:

compose.yml
# ...
volumes:
  - keycloak-and-mysql-volume:/var/lib/mysql
  - /path/to/file/keycloak_exported.sql:/docker-entrypoint-initdb.d/db.sql
# ...

More info of this at the official MySQL Docker Hub.

Caveats

If you try to add an Attribute to a user that contains a special character or unicode characters it will fail. This is something addressed on the Keycloak docs, but for the MySQL 5.5 version.

For this example we are using MySQL 8.0.27, so, when you export the database with Workbench, you'll see that there are a lot columns created like:

keycloak_exported.sql
-- ...
`VALUE` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL
-- ...

The default MySQL server character set and collation are utf8mb4 and utf8mb4_0900_ai_ci_ as stated on the docs, so we can safely remove the CHARACTER SET instruction on the keycloak_exported.sql to fix this and then import it in a new instance of MySQL so it gets created again with the correct charset and collation. So now, the column creation will look like:

keycloak_exported.sql
-- ...
`VALUE` varchar(255) DEFAULT NULL
-- ...

After this changes, we can add unicode characters to the user attributes.

Comments
If you have any doubt or question, or know how to improve this post, please feel free to write a comment.