【備忘録】Docker Composeで構築したquay.ioのKeycloakを本番モードで動かすためのメモ書き

# はじめに

この記事はDocker Composeで構築した[quay.io](https://quay.io/repository/keycloak/keycloak?tab=info)ベースのKeycloakを本番モードで実行するためのメモ書きです。

まずは通常の開発モードからオレオレ証明書を発行してHTTPS対応させて本番モードで動かせるようにします。

## 環境

OS: NixOS 23.11
Docker Compose: Docker Compose version 2.19.1
Keycloak: quay.io/keycloak/keycloak:22.0.1

# Keycloakを本番モードで動かすために

まずはKeycloakを開発モードで動かすための`compose.yml`ファイルです。

```yml:compose.yml
services:
  # keycloak
  keycloak:
    image: quay.io/keycloak/keycloak:22.0.1
    tty: true
    stdin_open: true
    ports:
        - 8080:8080
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: password
    command:
      - start-dev
```

こちらの`compose.yml`ファイルをもとにKeycloakを本番モードで動かすことができるようにします。

Keycloakを本番モードで動かすためのコマンドは、[Configuring Keycloak
 Starting Keycloak in production mode
](https://www.keycloak.org/server/configuration#_starting_keycloak_in_production_mode)で紹介されているように、`start`です。これは`compose.yml`ファイルの`command`の部分を書き換えることで実現できます。

しかし現状の設定のままで本番モードを動かそうとするとエラーが発生してしまいます。

```bash
ERROR: Unexpected error when starting the server in (production) mode
ERROR: Failed to start quarkus
ERROR: Strict hostname resolution configured but no hostname setting provided
```

これは、上記のサイトにもありますが、起動時にホスト名が設定されており、HTTPS/TLS設定が利用可能であることを期待されているためです。

# Keycloakを本番モードで動かせるようにする

## ホスト名の設定

まずはホスト名の設定を行います。

ホスト名の設定に関しては、

https://www.keycloak.org/server/hostname

のページで詳しく解説されています。

今回はDocker Composeを使用していますので、`KC_HOSTNAME`という環境変数にホスト名を渡してあげるだけで良いです。

## HTTPS対応

続いてHTTPS対応を行います。

こちらの設定に関しては、

https://www.keycloak.org/server/enabletls

と、

https://www.keycloak.org/server/outgoinghttp

のページで詳しく解説されています。

証明書と秘密鍵を用意し、`KC_HTTPS_CERTIFICATE_FILE`環境変数と`KC_HTTPS_CERTIFICATE_KEY_FILE`環境変数の場所にそれぞれ配置します。今回はオレオレ証明書を使用します。

```bash
$ openssl req -x509 -out keycloak.crt -keyout keycloak.key -newkey rsa:2048 -nodes -sha256 -subj '/C=JP'
$ chmod 640 keycloak.key
```

なお証明書の発行時に空のサブジェクトDNを渡すと怒られてしまいます。

```bash
2023-08-11 13:08:50,633 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to start server in (production) mode
2023-08-11 13:08:50,634 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Unable to start HTTP server
2023-08-11 13:08:50,634 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: io.vertx.core.VertxException: java.security.cert.CertificateParsingException: Empty issuer DN not allowed in X509Certificates
2023-08-11 13:08:50,634 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: java.security.cert.CertificateParsingException: Empty issuer DN not allowed in X509Certificates
2023-08-11 13:08:50,634 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Empty issuer DN not allowed in X509Certificates
2023-08-11 13:08:50,634 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) For more details run the same command passing the '--verbose' option. Also you can use '--help' to see the details about the usage of the particular command.
```

また秘密鍵にはグループ読み込み権限を与える必要がありました。

```bash
2023-08-11 13:02:46,186 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: Failed to start server in (development) mode
2023-08-11 13:02:46,186 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) ERROR: /etc/x509/https/keycloak.key
2023-08-11 13:02:46,187 ERROR [org.keycloak.quarkus.runtime.cli.ExecutionExceptionHandler] (main) For more details run the same command passing the '--verbose' option. Also you can use '--help' to see the details about the usage of the particular command.
```

`--verbose`オプションを付けて詳細を確認してね！と、ありますがヘルプを確認してもこのオプションは存在しないという罠....

## compose.ymlファイルの修正

最終的な`compose.yml`ファイルは以下のようになります。証明書と秘密鍵のマウント先に関しては、[Keycloak SSL setup using docker image](https://stackoverflow.com/questions/52674979/keycloak-ssl-setup-using-docker-image)を参考にしました。

```yml:compose.yml
services:
  # keycloak
  keycloak:
    image: quay.io/keycloak/keycloak:22.0.1
    tty: true
    stdin_open: true
    volumes:
      - ./certs/keycloak.crt:/etc/x509/https/keycloak.crt
      - ./certs/keycloak.key:/etc/x509/https/keycloak.key
    ports:
        - 8443:8443
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: password
      KC_HOSTNAME: localhost
      KC_HTTPS_CERTIFICATE_FILE: /etc/x509/https/keycloak.crt
      KC_HTTPS_CERTIFICATE_KEY_FILE: /etc/x509/https/keycloak.key
    command:
      - start
```

`docker compose up`コマンドを実行することで、Keycloakが本番モードで動くようになります。
[https://localhost:8443](https://localhost:8443/)にアクセスするとKeycloakのページが表示されるはずです。

# まとめ

今回の記事ではDocker Composeで構築したKeycloakを本番モードで動かすための方法をまとめました。

`--verbose`オプションが見当たらず、秘密鍵の権限周りで苦戦したため、記事にまとめることを決めました。`KC_LOG_LEVEL`という環境変数が用意されていることを道中で見つけたのですが、こちらを設定しても解決策を見つけることができず。

なおデータベースなど、その他の設定については、

https://www.keycloak.org/server/all-config

のページから確認することができます。