LoginSignup
9
8

More than 5 years have passed since last update.

DockerでとりあえずJettyを動かす最低限の構成をメモ

Posted at

導入

この記事の目的

備忘録です。

やったこと

DockerのJettyイメージを使って、JavaサーブレットのHello Worldを実装しました。
サーブレットやWARに必要なものをいつも忘れてしまうので、メモとして残します。

使ったツール

  • Docker
  • Docker Compose
  • Jetty
  • Gradle

Docker

コンテナ型仮想化基盤。
Jettyのインストールの手間を省くため、そのままで動く仮想環境を構築するために使いました。

Docker Compose

複数のDockerコンテナの管理を補助するツール。
なくてもDockerは使えますが、dockerコマンドに渡す引数が複雑になりがちなので、それらをYAMLファイルとして残せるツールとして使いました1

Jetty

Javaサーブレットコンテナ。
WARをデプロイして使えるアプリケーションサーバーです。

Gradle

Javaビルドツール。
依存関係の定義と、WARをビルドするために使いました。

検証環境

  • macOS Sierra (10.12.3)
  • Docker for Mac (1.13.0)
  • Docker Compose (1.10.0)
  • JDK (1.8.0_102)
  • Gradle (3.2.1)

実施手順

Jettyコンテナを起動する

作業フォルダー直下に以下のファイルを作成します:

docker-compose.yml
# バージョン2記法で記述する
version: '2'

# 起動するコンテナを定義する
services:

    # Jettyコンテナ
    jetty:
        # Dockerfileからビルドするのではなく、Docker Hubの公式イメージを使う
        # サイズが小さいAlpineベースのイメージを使う
        image: jetty:9.4.1-alpine

        # コンテナ内のポートをホストに公開する
        # 書式 "HOST:CONTAINER"
        ports:
            # Jettyのポートを同じ番号でホストに公開する
            - "8080:8080"

docker-compose.ymlと同じフォルダーでdocker-compose upコマンドを実行します。
すると以下のようにJettyコンテナが起動し、Jettyのログが表示されます:

Mac-mini-K:jetty-docker kazuma$ docker-compose up
Creating jettydocker_jetty_1
Attaching to jettydocker_jetty_1
jetty_1  | 2017-02-09 10:14:37.178:INFO::main: Logging initialized @460ms to org.eclipse.jetty.util.log.StdErrLog
jetty_1  | 2017-02-09 10:14:37.417:INFO:oejs.SetUIDListener:main: Setting umask=02
jetty_1  | 2017-02-09 10:14:37.426:INFO:oejs.SetUIDListener:main: Opened ServerConnector@6767c1fc{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
jetty_1  | 2017-02-09 10:14:37.427:INFO:oejs.SetUIDListener:main: Setting GID=101
jetty_1  | 2017-02-09 10:14:37.429:INFO:oejs.SetUIDListener:main: Setting UID=100
jetty_1  | 2017-02-09 10:14:37.434:INFO:oejs.Server:main: jetty-9.4.1.v20170120
jetty_1  | 2017-02-09 10:14:37.456:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///var/lib/jetty/webapps/] at interval 1
jetty_1  | 2017-02-09 10:14:37.477:INFO:oejs.AbstractConnector:main: Started ServerConnector@6767c1fc{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
jetty_1  | 2017-02-09 10:14:37.478:INFO:oejs.Server:main: Started @760ms

http://localhost:8080/ にアクセスすると、Jettyからの404が返ってくるので、起動確認ができます:

スクリーンショット 2017-02-09 19.18.48.png

WARを作成する

Eclipseのプロジェクトを作成する

作業フォルダーに、src/main/javaフォルダーを作成しておきます。
また、以下のファイルも作成し、同じフォルダーでgradle eclipseを実行します:

build.gradle
// Javaのビルドスクリプト

// プラグイン指定
// Javaをコンパイルするのに必要
apply plugin: 'java'

// フォルダーをEclipseプロジェクト化するのに必要
apply plugin: 'eclipse'

// WARを生成するのに必要
apply plugin: 'war'

// リポジトリーとしてMavenリポジトリーを指定
repositories {
    mavenCentral()
}

// 依存関係を記述する
dependencies {
    // providedCompile: コンパイル依存だがWARに含めない
    // サーブレットを作成するのに最低限必要なJARを追加
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0'
}

作業フォルダーがEclipseプロジェクトになるので、以下のようにEclipseへインポートしておきます:

スクリーンショット 2017-02-09 19.24.20.png

サーブレットとweb.xmlを作成する

以下のようなサーブレットクラスを作成します。
ネームスペースは任意のものをつけてください:

src/main/java/com/github/kazuma1989/jetty/TestServlet.java
package com.github.kazuma1989.jetty;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=UTF-8");

        // GETメソッドのときは、パラメーターによらず Hello World! を返すのみ
        PrintWriter out = resp.getWriter();
        out.println("Hello World!");
    }
}

また、src/main/webapp/WEB-INFフォルダーを作成し、以下のファイルを作成します:

src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         id="WebApp_ID"
         version="3.1">

    <display-name>TestDynamicWebApp31</display-name>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.github.kazuma1989.jetty.TestServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/TestServlet/*</url-pattern>
    </servlet-mapping>
</web-app>

<servlet-class>com.github.kazuma1989.jetty.TestServlet</servlet-class>の箇所は、先ほど作成したサーブレットクラスのFQCNを記入します。

※ 参考リンク [備忘録!]GradleでWARを作る - Qiita

作業フォルダーでgradle warコマンドを実行すると、build/libs以下にWARが生成されます:

Mac-mini-K:jetty-docker kazuma$ gradle war
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:war UP-TO-DATE

BUILD SUCCESSFUL

Total time: 0.868 secs
Mac-mini-K:jetty-docker kazuma$ ls build/libs/
jetty-docker.war

JettyにWARをデプロイする

docker-compose.ymlの最後に以下の記述を追加します。
ホストのbuild/libsフォルダーにあるWARを、Jettyコンテナ内の/var/lib/jetty/webappsに置くことでデプロイします:

docker-compose.yml

        # コンテナ内のフォルダーをホストとマウントする
        # 書式 HOST(docker-compose.ymlからの相対パス):CONTAINER(絶対パス)
        volumes:
            # Jettyのデプロイフォルダーに、GradleがWARを生成する先をマウントする
            # foo.war には http://localhost:8080/foo でアクセスできるようになる
            - ./build/libs:/var/lib/jetty/webapps

docker-compose.ymlを修正したので、Jettyコンテナを作り直します。
念のため削除して、再生成します:

Mac-mini-K:jetty-docker kazuma$ docker-compose stop && docker-compose rm -f
Stopping jettydocker_jetty_1 ... done
Going to remove jettydocker_jetty_1
Removing jettydocker_jetty_1 ... done
Mac-mini-K:jetty-docker kazuma$ docker-compose up
Creating jettydocker_jetty_1
Attaching to jettydocker_jetty_1
jetty_1  | 2017-02-09 10:45:01.994:INFO::main: Logging initialized @524ms to org.eclipse.jetty.util.log.StdErrLog
jetty_1  | 2017-02-09 10:45:02.278:INFO:oejs.SetUIDListener:main: Setting umask=02
jetty_1  | 2017-02-09 10:45:02.289:INFO:oejs.SetUIDListener:main: Opened ServerConnector@6767c1fc{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
jetty_1  | 2017-02-09 10:45:02.289:INFO:oejs.SetUIDListener:main: Setting GID=101
jetty_1  | 2017-02-09 10:45:02.291:INFO:oejs.SetUIDListener:main: Setting UID=100
jetty_1  | 2017-02-09 10:45:02.297:INFO:oejs.Server:main: jetty-9.4.1.v20170120
jetty_1  | 2017-02-09 10:45:02.320:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///var/lib/jetty/webapps/] at interval 1
jetty_1  | 2017-02-09 10:45:02.623:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=71ms
jetty_1  | 2017-02-09 10:45:02.832:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
jetty_1  | 2017-02-09 10:45:02.832:INFO:oejs.session:main: No SessionScavenger set, using defaults
jetty_1  | 2017-02-09 10:45:02.833:INFO:oejs.session:main: Scavenging every 600000ms
jetty_1  | 2017-02-09 10:45:03.113:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@20398b7c{/jetty-docker,file:///tmp/jetty/jetty-0.0.0.0-8080-jetty-docker.war-_jetty-docker-any-8862506664121339371.dir/webapp/,AVAILABLE}{/jetty-docker.war}
jetty_1  | 2017-02-09 10:45:03.120:INFO:oejs.AbstractConnector:main: Started ServerConnector@6767c1fc{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
jetty_1  | 2017-02-09 10:45:03.121:INFO:oejs.Server:main: Started @1650ms

jetty-docker.warを読み込んでいるログが出力されています。
再び http://localhost:8080/ にアクセスすると、先ほどはなかったリンクが表示され、WARが読み込まれたことを示しています:

スクリーンショット 2017-02-09 19.46.33.png

http://localhost:8080/jetty-docker/TestServlet/foo (fooの部分は任意)にアクセスすると、作成したサーブレットが実行され、成功です:

スクリーンショット 2017-02-09 19.49.51.png

まとめ

自作のサーブレットクラスをJettyにデプロイし、実行する手順メモを残しました。
作成したファイルは以下の4つだけなので、非常に単純です。

build.gradle
docker-compose.yml
src/main/java/com/github/kazuma1989/jetty/TestServlet.java
src/main/webapp/WEB-INF/web.xml

Javaサーブレットで手取り早く何かを試したいときに有用かもしれません。


  1. Jettyコンテナを8080ポートで起動するだけでも、docker run -p "8080:8080" -t jetty:9.4.1-alpineのように、シェルファイルに書き残したくなる引数の多さです。ボリュームをマウントするとなおさらです。 

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8