Gradleを使用して、httpサーバーでDockerコンテナーを収集します

画像 こんにちはHabr!



次の問題が発生しました:最小数の依存関係を持つ単純なWebサーバーを作成します。 この場合、ドッカーコンテナーとして展開されます。 サーバー自体を実装するには、 GrizzlyWebServerを使用します 。 Benjamin Muschko(bmuschko)のdockerプラグインでGradleをビルドします。



このツールの選択は偶然ではなく、私はアンドロイド用に開発しており、JavaとGradleは他のものよりも私に近いです。 この記事では、アプリケーションを作成してからdockerで起動するまでのプロセス、考えられる問題とその解決策について詳しく説明します。



それでは、始めましょう:サーバー。



IntelliJ IDEAで新しいGradleプロジェクトを作成します。



画像



画像



空のプロジェクトが作成されました。main()メソッドでHabrWebServerクラスを追加します。 依存関係のbuild.gradleに行を追加します。



compile group: 'org.glassfish.grizzly', name: 'grizzly-http-server', version: '2.3.28'
      
      





最も単純なサーバーのコード
 public class HabrWebServer { private static final Logger LOGGER = Grizzly.logger(HabrWebServer.class); public static void main(String[] args) { // create a basic server that listens 0.0.0.0:8080 final HttpServer server = HttpServer.createSimpleServer(); final ServerConfiguration config = server.getServerConfiguration(); // Map the path, '/', to the Handler config.addHttpHandler(new HabrHandler(), "/"); try { server.start(); System.out.println("The server is running. \nPress enter to stop..."); System.in.read(); } catch (IOException ioe) { LOGGER.log(Level.SEVERE, ioe.toString(), ioe); } finally { server.shutdownNow(); } } private static class HabrHandler extends HttpHandler { @Override public void service(Request request, Response response) throws Exception { response.setContentType("text/plain"); response.getWriter().write("Hello Habrahabr!"); } } }
      
      







プロジェクトディレクトリでコンソールを開き、「./ gradlew assemble-BUILD SUCCESSFUL」と入力します。

すでに集めたもの。



しかし、1つの不快な点があります。ideのインポートは機能せず、サーバークラシックは赤で強調表示されます。



画像



このように扱われます-魔法の更新ボタンを見つけてクリックする必要があります-GradleプロジェクトとIntelliJ IDEAプロジェクトの変更の同期



ここでアプリケーションをローカルで実行します。これには、 Gradleの「アプリケーション」プラグインを使用します



build.gradleで次の行を追加します。



 apply plugin: 'application' mainClassName = 'ru.test.HabrWebServer'
      
      





アプリケーションを収集してインストールします。



  ./gradlew installDist
      
      





/ habrServer / build / install / habrServer / binフォルダーに移動します。 アプリケーションを起動します。



 ./habrServer
      
      





ブラウザを開くと、サーバーは応答しますが、待っているものは応答しません。



画像



サーバーを作成するときに、createSimpleServer()メソッドは、所有していない静的コンテンツを提供する最初のハンドラーをインストールし、ハンドラーに到達しません。 サーバー作成コードを変更します。



  public static void main(String[] args) { final HttpServer server = createServer("0.0.0.0", 8080); ... } public static HttpServer createServer(String host, int port) { HttpServer server = new HttpServer(); NetworkListener listener = new NetworkListener("grizzly", host, new PortRange(port)); server.addListener(listener); return server; }
      
      





アプリケーションをdockerコンテナとしてビルドすることは残ります。

ローカルdockerのインストールから始めましょう。

Dockerをインストールすると、サーバーはUNIXソケットでのみリッスンします。 TCP経由のローカルアクセスを有効にします。



ファイル/lib/systemd/system/docker.serviceで、次の行を見つけて編集します。



 ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375
      
      





すべてのユーザーの設定を変更するため、このファイルを変更することは完全に正しいわけではありませんが、私の場合は私のマシンでのテストに適しています。



コンテナを組み立てるには、 bmuschko Gradle Dockerプラグインを使用します



最終build.gradle
 group 'habrServer' version '1.0-SNAPSHOT' apply plugin: 'java' apply plugin: 'application' apply plugin: 'com.bmuschko.docker-java-application' apply plugin: 'com.bmuschko.docker-remote-api' import com.bmuschko.gradle.docker.tasks.container.DockerCreateContainer mainClassName = 'ru.test.HabrWebServer' buildscript { repositories { jcenter() } dependencies { classpath 'com.bmuschko:gradle-docker-plugin:3.0.3' } } docker { url = 'http://127.0.0.1:2375' javaApplication { maintainer = 'Dmitry Barkalov "xxx@xxx.xxx"' ports = [8080] tag = 'habrwebserver' } } task createDocker(type: DockerCreateContainer) { dependsOn dockerBuildImage targetImageId { dockerBuildImage.getImageId() } portBindings = ['8080:8080'] } repositories { mavenCentral() jcenter() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' compile group: 'org.glassfish.grizzly', name: 'grizzly-http-server', version: '2.3.28' }
      
      







コンテナを組み立ててインストールします。



  ./gradlew createDocker
      
      





画像



発射!



画像



ブラウザで開きます。



画像



解決されていない問題が1つ残っています。アプリケーションはSystem.in.read()のメインスレッドで待機します。 したがって、-iスイッチを使用してdockerを起動します。 (接続されていない場合でも、STDINを開いたままにします。 ) stdinはコンテナに接続されたままです。 ほとんどの場合、悪魔の形でアプリケーションを作成する必要はありません。ドッカー自体がそれを悪魔にすることができます。 stdinとの対話を削除し、アプリケーションを停止できるようにする必要があります。 これはまだ見られません。 誰かが知っているなら、コメントを書いてくれて、感謝します。



ご清聴ありがとうございました。この記事が誰かに役立つことを願っています。

githubのプロジェクトコード。



All Articles