KeycloakをMariaDBで動かせるように四苦八苦したので手順。かなりてこずりました。

環境


  • MariaDB 10.3.2
  • MariaDB JDBC 2.2.2
  • Keycloak 3.4.3 Final

上記の組み合わせでやってます。MariaDBがハマりどころです。

構築の前に


構築の前に今回詰まった点を何点か記載しておきます。また、前述のとおりMariaDB 10.3系でやってますが、そもそもMariaDB 10.3はこの記事を書いている時点は開発中(stableでない)です。

MariaDBのバージョン


まず、こちらのIssueに起票されていますがMariaDBが10.3.3以下でないといけません。そうでないと起動時に下記のようなエラーが発生します。

1
2
3
4
5
6
7
8
//メッセージが長かったので適当に改行してます。
ERROR [org.keycloak.connections.jpa.updater.liquibase.conn.DefaultLiquibaseConnectionProvider] (ServerService Thread Pool -- 58)
Change Set META-INF/jpa-changelog-1.5.0.xml::1.5.0::bburke@redhat.com failed.
Error: (conn=10) Yr SQL syntax;
check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INT NULL DEFAULT 30, ADD ALGORITHM VARCHAR(36) NULL DEFAULT 'HmacSHA1'' at line 1
[Failed SQL: ALTER TABLE keycloak.CREDENTIALEFAULT 0, ADD DIGITS INT NULL DEFAULT 6, ADD PERIOD INT NULL DEFAULT 30, ADD ALGORITHM VARCHAR(36) NULL DEFAULT 'HmacSHA1']:
liquibase.exception.DatabaseException: (conn=10) You have an error in your SQL syntax; check the manual that correserver version for the right syntax to use near 'INT NULL DEFAULT 30, ADD ALGORITHM VARCHAR(36) NULL DEFAULT 'HmacSHA1'' at line 1
[Failed SQL: ALTER TABLE keycloak.CREDENTIAL ADD COUNTER INT NULL DEFAULT 0, ADD DIGITS INT NULL DEFAULT 6, AULT 30, ADD ALGORITHM VARCHAR(36) NULL DEFAULT 'HmacSHA1']

もともと、MariaDB 10.3.5で構築しようとしていたのですが、上記のエラーが出たので10.3.2まで下げました。するとエラーは出なくなりました。

文字コード


文字コードはutf8でないとダメでした。utf8mb4だと下記のようにエラーがでます。

1
2
3
CATE VARCHAR(4000)]: liquibase.exception.DatabaseException: (conn=14) Row size too large. 
The maximum row size for the used table type, not counting BLOBs, is 65535.
This includes storage overhead, check the manual. You have to change some

こちらのIssueに「--innodb_large_prefix=1を設定してみてください」的な回答もあるのですが、このオプションは MariaDB 10.3.1で消えてます。そもそも、一旦、10.2に下げてオプションを付与して試してみても同じメッセージが出ました。

※ 10.3は今のところ開発中(stableでない)ので、このオプションが今後も削除されたままなのかはわかりません

構築


MariaDBについて書いたところで構築手順を書いていきます。この公式ドキュメントを見ながら頑張ります。公式はPostgreSQLをサンプルとして書いてありますが、基本的には同じです。前述したバージョンとか文字コードのあたりが最もハマるポイントです。

Keycloak自体はすでにダウンロードしてきているものとします。また、MariaDBはutf8で構築済みでkeycloak用のスキーマも作成しているものとします。

JDBC向けのディレクトリ作成


まず、JDBC用にディレクトリを作成します。

1
modules/system/layers/keycloak/org/

上記のディレクトリの下にMariaDBのJDBCディレクトリを作成します。

1
2
3
mkdir mariadb
//さらにmariadbの下にjdbcディレクトリを作成する
mkdir jdbc

Javaのパッケージ命名規約に従って探すっぽいのでmariadb/jdbcというパスで作成する必要があります。このパスが正しくないと、起動時に下記のエラーが表示されます。

1
2
3
4
11:28:13,906 ERROR [org.jboss.as.controller.management-operation] (ServerService Thread Pool -- 26) WFLYCTL0013: Operation ("add") failed - address: ([
("subsystem" => "datasources"),
("jdbc-driver" => "mariadb")
]) - failure description: "WFLYJCA0041: Failed to load module for driver [org.mariadb.jdbc]"

JDBCダウンロード & 設定


次に下記からJDBCをダウンロードしてきます。

About MariaDB Connector/J

今回は2.2.2を使用したので、以降のサンプルはすべて2.2.2で記述します。ダウンロードしたバージョンに合わせて適宜変更してください。

次に、先ほど作成したmariadb/jdbcのディレクトリにmodule.xmlを作成して下記を記述します。

  • module nameorg.mariadb.jdbcを記述
  • resource-rootにJDBCのファイルのパスを記述
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" ?>
<module xmlns="urn:jboss:module:1.3" name="org.mariadb.jdbc">
<resources>
<resource-root path="mariadb-java-client-2.2.2.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>

設定ファイルをいじくる


configuration配下のstandalone.xmlをいじくっていきます。冗長構成をとる場合はstandalone-ha.xmlで設定するようです。以降はstandalone.xmlの設定についての記述です。

ExampleDSの削除

下記のような要素が見つかると思いますがExampleDSは不要なので、まずこいつを消します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<!--ここから消す-->
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<!--ここまで消す-->
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<drivers>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>

DB接続先設定

次に、上記の<datasource>の要素を下記のように変更します。

1
2
3
4
5
6
7
8
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true">
<connection-url>jdbc:mariadb://localhost:3306/keycloak?useUnicode=true&amp;characterEncoding=utf8</connection-url>
<driver>mariadb</driver>
<security>
<user-name>データベースユーザ名</user-name>
<password>データベースパスワード</password>
</security>
</datasource>

この時に<connection-url>のパラメータは&amp;とエスケープしてやる必要があります。

参考
XMLにおいて アンパサンド(&)はエスケープが必要

ドライバ変更

ドライバをMariaDBに変更します。前述の部分の<drivers>要素を下記のように変更します。

1
2
3
4
5
<drivers>
<driver name="mariadb" module="org.mariadb.jdbc">
<xa-datasource-class>org.mariadb.jdbc.MariaDbDataSource</xa-datasource-class>
</driver>
<drivers>

バインディング変更

最後にdefault-bindingsという要素を探してdatasourceのExamlpleDSKeycloakDSに変更します。

1
2
3
4
5
6
7
<!--下記の要素は実際のstandalone.xmlでは改行されてません-->
<default-bindings context-service="java:jboss/ee/concurrency/context/default"
datasource="java:jboss/datasources/KeycloakDS"
managed-executor-service="java:jboss/ee/concurrency/executor/default"
managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default"
managed-thread-factory="java:jboss/ee/concurrency/factory/default"
/>

以上で設定は終わりです。

動かす


これでbin配下のstandalone.shを動かせば起動します。Windowsの場合はstandalone.batです。localhost:8080にアクセスすると下記のような画面が表示されると思います。

されない場合は起動時のエラーや公式ドキュメントやMariaDBのJDBCのドキュメントなどなど…を参考にしながら確認します。また、以前書きましたがデフォルトだとローカルホスト以外からアクセスできません