Docker で Quarkus ライブコーディングを使用する方法

Docker で Quarkus ライブコーディングを使用する方法

ここ LogicMonitor では、実験を行い、新しいことを試すのが好きです。 実際、私たちの核となる信条の XNUMX つは、「毎日をより良くする」ことです。 これは、新しいことを学び、実験し、革新し、チャンスをつかむことに常に飢えていることを意味します。

私たちが最近実験している (そして大好きな!) ものの XNUMX つは、Quarkus フレームワークです。 軽量であることと、Kubernetes を念頭に置いてゼロから構築されていることが気に入っています。 しかし何よりも、私たちの開発者は妥協のない優先順位付けを気に入っています。 開発者の喜び.

開発者の喜びとは? Quarkus チームは簡単に言うと、Quarkus を使用することは楽しいものでなければなりません。 私にとって、それは Quarkus が私を笑顔にする小さなことです。 それを可能にする多くの機能がありますが、私が最も頻繁にニヤニヤしている機能は何ですか? それは簡単です。ライブ コーディングです。

ライブ コーディングは、コードを再コンパイルまたは再デプロイする必要なく、ソース コードを変更し、それらの変更をデプロイされたアプリケーションに反映させる機能です。 これは、開発ループを強化するのに最適であり、サービスの次のイテレーションを少し速くプッシュするのに役立ちます.

そのため、ライブ コーディングについて既にすべて知っている場合でも、まだ理解しようとしている場合でも、私たちはあなたをカバーします。 最初の Quarkus アプリを作成する方法、ローカルで開発モードで実行してライブ コーディングを使用する方法、Docker で同じアプリを実行する方法、Quarkus アプリを実行中にライブ コーディングを機能させる方法について説明します。 Docker コンテナ。 独自の製品コードにこれを実装する予定がある場合に留意すべきいくつかの落とし穴についても指摘します。

行こう!

TL; DR

お急ぎの方、またはライブ コーディングの基本を既に知っている方のために、既存の Quarkus アプリケーションがあると仮定して、Docker でライブ コーディングを有効にする手順を次に示します。

  1. 加える QUARKUS_LAUNCH_DEVMODE 環境変数を Docker コンテナーに追加し、次のように設定します。 tストリート
  2. 次の構成を application(-dev).properties ファイル:
quarkus.package.type=mutable-jar
quarkus.live-reload.password=changeit
quarkus.live-reload.url=http://localhost:8080
  1. jar をビルドし、Docker イメージをビルドし、Docker コンテナーを実行します。
  2. を使用してコンテナに接続します
./gradlew quarkusRemoteDev

上記の設定を入れた場合 application.properties or

./gradlew quarkusRemoteDev -Dquarkus.profile=dev

それらを入れた場合 application-dev.properties.

Gradle を使用しない場合、Quarkus は Maven もサポートします。 Maven を使用する場合、対応するコマンドは次のようになります。 ./mvnw quarkus:remote-dev.

以上が基本的な手順です。 以下では、これがどのように機能するかを非常に基本的なレベルで説明します。これにより、ほぼすべての人がローカルの Docker コンテナーでライブ コーディングを快適に使用できるようになります。

初めての Quarkus アプリを作成するにはどうすればよいですか?

Quarkus は、新しいサービスのフレームワークをセットアップする複数の方法を提供します。 Quarkus CLI はとても便利なので気に入っています。 UI が必要な場合は、Quarkus チームが開始用の優れた Web ページを提供しています。 https://code.quarkus.io/

このチュートリアルでは Quarkus CLI を使用します。Quarkus CLI は非常にシンプルで、Java と好みのビルド ツールがまだインストールされていない場合は自動的にインストールされるためです。 私たちと一緒にフォローする予定がある場合は、Quarkus CLI のセットアップ手順をここで見つけることができます。 https://quarkus.io/get-started/

それが完了したら、次のコマンドを実行するだけで、最初のアプリケーションを簡単に作成できます。

quarkus create app --gradle docker-live-coding

このコマンドは、「docker-live-coding」という名前の新しいディレクトリにビルド ツールとして Gradle を使用して新しいアプリを作成するよう Quarkus CLI に指示します。 ここLogicMonitorではGradleを使用しているため、ここで使用しています。 Maven または JBang に慣れている場合、Quarkus CLI はそれらをサポートします。 Gradle の代わりに好みのビルド ツールを使用するには、以下のコマンドの一部を変更する必要があることに注意してください。

実行してみてください quarkus -h して、CLI で他に何ができるかを確認してください。

コードを見てみる

Quarkus CLI のおかげで、必要最小限のマイクロサービスができました! これには、API エンドポイント、そのエンドポイントの単体テスト、および役立つ Dockerfiles が含まれます。

まず、エンドポイントを見てみましょう。 これを行うには、 src/main/java/org/acme/GreetingResource.java お気に入りの IDE またはテキスト エディターで:

@Path("/hello")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "Hello from RESTEasy Reactive";
    }
}

それはかなり簡単です。 エンドポイントに GET 要求を送信すると、応答としてフレンドリーな挨拶が返されます。 きちんとした!

単体テストは次の場所にあります src/main/test/java/org/acme/GreetingResourceTest.java:

@QuarkusTest
public class GreetingResourceTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/hello")
          .then()
            .statusCode(200)
            .body(is("Hello from RESTEasy Reactive"));
    }

}

これも非常にシンプルです。 GET リクエストが「/hello」エンドポイントに送信されると、本文に親しみやすい小さな挨拶が含まれる 200 ステータス コードのレスポンスを受信することが期待されます。

最後に、次の場所に Dockerfile があります。 src/main/docker. CLI は、デフォルトで XNUMX つの異なるファイルを作成します。 Dockerfile.jvm, Dockerfile.legacy-jar, Dockerfile.native, Dockerfile.native-micro.

Dockerfile.jvm Quarkus のデフォルトの JAR パッケージである fast-jar で使用します。 さまざまな JAR オプションにあまり慣れていない場合は、ここから始めるのが最適です。 Dockerfile.legacy-jar これは、古いデフォルトの Quarkus JAR パッケージ (Quarkus 1.12 より前) をまだ使用している私たちのためのものです。 これは、既存のプロジェクトに取り組んでいる人にのみ役立ちます。 Dockerfile.native & Dockerfile.native-micro ネイティブ実行可能ファイルをビルドするためのものです。 これは、非常に小さなイメージ、小さなメモリ フットプリント、超高速の起動を可能にする Quarkus の優れた機能の XNUMX つです。

物事をシンプルにするために、次のことに焦点を当てます。 Dockerfile.jvm このチュートリアルでは、

Quarkus アプリを実行するにはどうすればよいですか?

新しいプロジェクト ディレクトリで次のコマンドを実行するだけで、新しいアプリケーションをローカルですばやく簡単に実行できます。

quarkus dev

最終的に、アプリが実行中であることを知らせる次の出力が表示されます。

__  ____  __  _____   ___  __ ____  ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \  
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/  
2022-10-03 18:41:18,701 INFO  [io.quarkus] (Quarkus Main Thread) docker-live-coding-2 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.12.2.Final) started in 1.482s. Listening on: http://localhost:8080

2022-10-03 18:41:18,704 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2022-10-03 18:41:18,704 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy-reactive, smallrye-context-propagation, vertx]

そしてそのように、あなたのアプリはで実行されています localhost:8080.

実際、このコマンドは、ローカルで dev モードで Quarkus アプリケーションを実行しました。 開発モードは、Quarkus が提供するインタラクティブなターミナルへのアクセスを可能にする素晴らしいツールです & ライブコーディング。

Quarkus でコードをどのようにライブ化しますか?

さて、私たちは長い間話し合ってきましたが、このライブコーディングが実際に動作するのはいつになるのでしょうか? 二度言わなくてもいいからやってみよう!

まず、アプリケーションがどのように動作するかを見てみましょう。 新しいターミナル タブ/ウィンドウを開き、次のコマンドを入力します。

curl -w "\n" http://localhost:8080/hello

実行すると、次のメッセージが表示されます (単体テストと同じように!)。

Hello from RESTEasy Reactive

さて、それは十分に素晴らしいメッセージですが、考えてみると、相手の様子を聞かずに挨拶するのは失礼なことです. それを修正しましょう!

閉じた場合は、GreetingResource.java ファイルを再度開き、hello() メソッドに次の変更を加えましょう。

  public String hello() {
        return "Hello from RESTEasy Reactive. How are you?";
    }

保存したら、その curl コマンドをもう一度実行します。 何が見えますか?

Hello from RESTEasy Reactive. How are you?

そのように、コードの変更を使用するようにアプリケーションが更新されました while 走っていました。 それはどれほどクールですか? まだ笑っていますか? 🙂

それで、それはどのように起こったのですか? Quarkus アプリが開発モードで実行されている場合、受信リクエストを受信するたびに、アプリのソース コードが変更されたかどうかを確認するために保持されます。 変更されている場合、Quarkus は変更されたコードをすばやくコンパイルし、リクエストを実行する前にすぐにデプロイします。 私が言ったように、とてもクールです。

Docker でアプリを実行するにはどうすればよいですか?

まず、アプリケーションの JAR ファイルをビルドする必要があります。 Docker は、コンテナーの起動時にそれを使用します。 使用しているビルド ツールと、Quarkus CLI を使用しているかどうかに応じて、アプリケーションの JAR ファイルをビルドする方法がいくつかあります。

CLI の使用:

quarkus build

Gradle の場合は、リポジトリのルートに移動して次を実行します。

./gradlew build

Maven または JBang を使用している場合は、異なるが類似したコマンドを実行する必要があります ( Dockerfile.jvm ファイル!)。

上記に従って、変更を加えた場合 GreetingResource ビルド コマンドを実行する前に、変更を元に戻すか、単体テストを更新してください。 そうしないと、単体テストに合格しないため、ビルドは失敗します。

JAR ファイルをビルドしたら、Docker イメージをビルドできます。 先に述べたように、 Dockerfile.jvm このため。 イメージをビルドするには、ターミナルで次のコマンドを実行します。

docker build -f src/main/docker/Dockerfile.jvm -t quarkus/docker-live-coding .

コマンドの最後にあるドット (.) を忘れないでください。 これにより、Docker のビルド コンテキストが提供されます。

ここで、 -f src/main/docker/Dockerfile.jvm 引数は、Docker が使用したい Dockerfile を指していて、 -t quarkus/docker-live-coding 引数は、後で参照するために使用できるタグを画像に与えます。

イメージが作成されたら、実行に移します。

docker run -i --rm -p 8080:8080 quarkus/docker-live-coding

さて、同じように実行します curl 以前と同じようにコマンドを実行すると、元の (あまり丁寧ではない) 挨拶が表示されます。

しかし、前回のように変更を試みるとどうなるでしょうか。 一言で言えば:何も! ライブ コーディングは、いくつかの理由により、Docker ではそのままでは機能しません。 熱心な読者の中には、起動ログでこれらの問題の XNUMX つを見たことがあるかもしれません。

022-10-03 22:13:33,453 INFO  [io.quarkus] (main) Profile prod activated.

prod モードで実行している間は、dev モードの機能を使用することはできません。 他に何を変更する必要があるか見てみましょう。

Docker でライブ コーディングを機能させるにはどうすればよいですか?

アプリを開発モードで実行する必要があることはわかっているので、そこから始めましょう。

これを行うには、新しい環境変数を追加するだけです。 QUARKUS_LAUNCH_DEVMODEに設定し、 true. これを行うにはいくつかの方法がありますが、最も簡単な方法は、次の行を Dockerfile に追加することです。

ENV QUARKUS_LAUNCH_DEVMODE=true

個人的には維持したい Dockerfile.jvm 参照として変更されていないので、その内容を新しいファイルにコピーしました。 Dockerfile.dev、ファイルの下部に上記の行を追加しました。

FROM registry.access.redhat.com/ubi8/openjdk-11:1.11

ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'

COPY --chown=185 build/quarkus-app/lib/ /deployments/lib/
COPY --chown=185 build/quarkus-app/*.jar /deployments/
COPY --chown=185 build/quarkus-app/app/ /deployments/app/
COPY --chown=185 build/quarkus-app/quarkus/ /deployments/quarkus/

EXPOSE 8080
USER 185
ENV AB_JOLOKIA_OFF=""
ENV JAVA_OPTS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"

ENV QUARKUS_LAUNCH_DEVMODE=true

アフター パブリケーションでこれを読んでいる場合、Quarkus CLI が自動生成された Dockerfile を何らかの方法で変更した可能性があります。 上記のものとあなたのものに違いが見られても、心配しないでください。 環境変数を Dockerfile に追加する限り、問題はありません。

それが完了したら、Quarkus にビルド ファイルをミュータブルに変更するように指示する必要があります (コードをオンザフライで変更できるようにするため)。 これを行うには、 application.properties 内のファイル src/main/resources ディレクトリ。 これは、Quarkus CLI が自動的に生成した別のファイルであり、アプリの構成を決定する役割を果たします。 あなたはそれについてもっと学ぶことができます ここ.

開いたら、次の行を追加します。

quarkus.package.type=mutable-jar
quarkus.live-reload.password=changeit
quarkus.live-reload.url=http://localhost:8080

値のヒントとして、独自のパスワードを指定する必要があります quarkus.live-reload.password 構成。 確かに、ローカルで Docker の開発モード/ライブ コーディングのみを実行している場合は、セキュリティで保護されていないパスワードを使用するリスクはあまりありません。 ただし、ベスト プラクティスに従って、より安全なものに更新しても問題はありません。 実際、クラウドでライブ コーディングを実行する方法があるかもしれません *ヒント ヒント* – その場合、デフォルトのパスワードを使用したくないでしょう!

注:技術的には必要ありません quarkus.live-reload.url で構成する application.properties 値をコマンド ライン引数として指定できるためです (以下に例を示します)。 便利ですが、この方法をお勧めします。

アプリをビルドして実行するプロセスは、以前とほとんど同じです。

quarkus build # our code hasn't changed, but we added configs to application.properties
docker build -f src/main/docker/Dockerfile.dev -t quarkus/docker-live-coding . # use Dockerfile.jvm if you didn't make a Dockerfile.dev
docker run -i --rm -p 8080:8080 quarkus/docker-live-coding

これで、アプリはコンテナと開発モードで実行されますが、試してみると、ライブ コーディングはまだ機能しません。

ありがたいことに、これは簡単な解決策です。ローカル マシンに「リモート」マシンに接続するように指示するだけです (この例では、実際にはローカル マシンで実行されている Docker コンテナーですが、これは真のリモート マシンにも当てはまります)。 Quarkus アプリケーションがソースコードを監視できること。 これを行うには、別のターミナル ウィンドウを開き、次を実行します。

./gradlew quarkusRemoteDev

上記のように、 quarkus.live-reload.url の設定 application.properties 次のコマンドを実行して、アプリが実行されている場所を Quarkus が認識できるようにする必要があります。

./gradlew quarkusRemoteDev -Dquarkus.live-reload.url=http://localhost:8080

正常に接続された場合、次のようなログが表示されます。

> Task :quarkusRemoteDev
Listening for transport dt_socket at address: 5005
2022-10-03 15:39:37,025 INFO  [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 934ms
> :qu2022-10-03 15:39:37,531 INFO  [io.qua.ver.htt.dep.dev.HttpRemoteDevClient] (Remote dev client thread) Sending lib/deployment/appmodel.dat
2022-10-03 15:39:37,538 INFO  [io.qua.ver.htt.dep.dev.HttpRemoteDevClient] (Remote dev client thread) Sending app/quarkus-application.jar
2022-10-03 15:39:37,547 INFO  [io.qua.ver.htt.dep.dev.HttpRemoteDevClient] (Remote dev client thread) Sending quarkus-run.jar
2022-10-03 15:39:37,549 INFO  [io.qua.ver.htt.dep.dev.HttpRemoteDevClient] (Remote dev client thread) Connected to remote server

<=========----> 75% EXECUTING [3m 55s]
> :quarkusRemoteDev

それが完了したら、準備は完了です。 Docker でのライブ コーディングをお楽しみください。

しかし、もっとうまくできるでしょうか?

解決策をどのように改善しますか?

すべてが機能するようになったので、行った変更の影響について考える必要があります。 最も注目すべきは、新しい構成を追加したことです。

適格なプロファイルなしでこれらの構成を追加することにより (構成プロファイルの詳細については、こちらを参照してください。 ここ)、どのビルドを実行しても、これらの値がアプリケーションに渡されることが保証されています! ミュータブルな JAR を本番環境で実行したくないのは確かです。 それはただトラブルを求めているだけです。

ありがたいことに、Quarkus には簡単な解決策があります: 構成プロファイルです! これらのプロファイルは、アプリを実行する予定の環境に基づいて、アプリケーションに存在する必要がある構成を決定するのに役立ちます。

開発環境でのみライブ コーディングを実行したい場合は、dev プロファイルを利用できます。 これを行う最も簡単な方法は、次の名前の新しいファイルを作成することです。 application-dev.properties 元の場所と同じ場所に application.properties ファイル。 前の手順で追加した構成を元のプロパティ ファイルから新しい開発バージョンに移動するだけです。

現在、これらの構成は、開発モードでビルドするときにのみアプリケーションに渡されます。 他のプロファイルを使用する場合、これらの構成は単純に無視されます。

先に進んで、アプリケーションを再構築し、ライブ コーディングをテストしてみてください。 プロセスはほぼ同じですが、JAR をビルドするときに、Gradle (またはお気に入りのビルド ツール) に dev モードでビルドするように指示する必要があります。

quarkus build -Dquarkus.profile=dev

Quarkus がライブコーディングの URL とパスワードを認識できるように、リモートの開発セッションに接続するときに同じ引数を追加する必要があります。

./gradlew quarkusRemoteDev -Dquarkus.profile=dev

余分なクレジットとして、新しい引数なし​​でこのプロセスを実行してみて、ライブ コーディングに接続できるかどうかを確認してください (ネタバレ: できません)。

さらなる探求

ローカルの Docker セットアップでライブ コーディングを実行する方法がわかったので、クラウドで実行されているコンテナーでもライブ コーディングを使用できるかという問題があります。

答えはイエスです! Quarkus は、Kubernetes、Minikube、および Openshift でのライブ コーディングをサポートしています。 それぞれの完全な実装は、読者の演習として残しておきます。上記で説明したすべてのことから、作業を行うために必要なほとんどの情報が得られるはずです。

まとめ

このブログ投稿では、Quarkus アプリをゼロから作成する方法、dev モードでローカルに実行する方法、ライブ コーディングをローカルで使用する方法、アプリをローカルの Docker コンテナーにデプロイする方法、アプリがローカルの Docker で実行されている間にライブ コーディングを使用する方法を学びました。このプロセスをプロの開発環境で使用するために改良する方法. さらに詳しく知りたい場合は、Quarkus チームがまとめた素晴らしいガイドをすべてチェックしてください。 https://quarkus.io/guides/