実用性を考えたKtorのホットリロード設定
概要
JVM初心者がKtorを少し触ってみたところ、ホットリロードを機能させるのに苦労したのでそのまとめです。 以下の前提で実用的な設定方法を考えてみました。
- KtorアプリケーションはDockerコンテナで実行される
- ローカル開発環境ではDocker Composeで複数のコンテナを起動する
- 当然ローカル開発環境でのみホットリロードを有効にする
結論
- 開発環境用のDockerfile.devを用意する
- その中で「アプリケーションの継続的なビルド」「Development modeでのアプリケーションの継続的な実行」を行う
ENTRYPOINT ["bash", "-c", "./gradlew -t build & ./gradlew run -t -Dio.ktor.development=true"] - compose.ymlでDockerfile.devを指定してサービスを起動する
レポジトリ
docker compose upでアプリを起動します。localhost:8080にアクセスするとhello worldが表示されます。
api/src/main/kotlin/com/example/Routing.ktでAPIのコードを編集することで、ホットリロードが機能していることを確認できます。
解説
Development mode
KtorをDevelopment modeで起動する必要があり、リンクに記載の通り3つの方法があります。
- Ktorの設定ファイル(application.conf || application.yaml)で設定
- Gradleの設定ファイル(build.gradle.kts)で設定
- Gradleのコマンドラインオプションで設定
1と2の方法は、何らかの方法で設定ファイルの内容を動的にしなければ本番環境でもDevelopment modeで起動してしまうのでややこしいです。
今回は3の方法を採用し、開発環境専用のDockerfileを用意しその中でコマンドラインオプションを指定してKtorを起動することにしました。
ホットリロードを機能させる
KtorにはAuto-reloadという機能がありますが、これは一般的なホットリロードではありません。
ビルドされた.classファイルを監視し、実行中のアプリケーションに即座に反映するというものです。ソースコードそのものを変更しても実行中のアプリケーションには反映されせん。
なのでホットリロードを機能させるには、上記ドキュメントに記載の./gradlew run -t -Dio.ktor.development=trueとは別に./gradlew -t buildも実行して、同時に継続的ビルドも行う必要があります。
./gradlew -t build & ./gradlew run -t -Dio.ktor.development=true
おわりに
「Auto-reload ≠ ホットリロード」ということに気づくのに時間がかかりはまりました。
他には本筋ではないですが、VS Codeからライブラリのソースコードに定義ジャンプできないという問題にもはまりました。こちらは結局解決できず、IntelliJ(無料版)に乗り換えたらすぐ解消しました。JVM書く場合はIntelliJの方が無難そうですね。。
Discussion