sobreera's diary

技術系の何かを書き綴っていく予定

IntelliJ Community Editionを使ってGradle + Docker + Tomcat環境を構築する

ありそうでなかったネタなので書きます。
Ultimate Edition使えばこんな面倒なことしなくて済むので、CE版しか使えない人向けです。

はじめに

Tomcatは/usr/local/tomcat/webappsをwatchしているので、そこにwarをビルドするようにすれば自動的にデプロイされます。

なので流れとしては
1. dockerでtomcatのwebappsとwarが出力されるディレクトリをバインド
2. gradleでwarをビルド
3. tomcatがホットリロード

といったような感じ。一度コンテナ起動した後はエディタでRunしたときにwarがビルドされるようにすればスムーズに開発できますね。
まあこれだけなんですが、gradleのwarプラグインとか知ってないとコケがちなので書く価値はあるかなと。
では実際に構築していきます。

とりあえずIntelliJでGradle > Javaにチェックで新規プロジェクトを作成します。
その他のプロジェクト設定はよしなに。

Dockerプラグインの設定

とりあえずDocker integrationプラグインをインストールしてない人はしてください。
MarketplaceでDockerというプラグインがあったらそれです。

再起動してDocker自体の設定を行います。
Build, Execution, Deployment > Dockerを選んで+を押して新しいDockerへの接続設定を追加します。
Nameは何でも構いません。
Connect to Docker daemon withのところはmacならデフォルトでDocker for Macが選択されていると思うのでそれだけで構いません。便利になった。

Gradleの設定

次にbuild.gradleをいじります

pluginsに id ‘war’を追加。これがwarにビルドするためのプラグインです。詳しくはこちらを御覧ください。
第26章 War プラグイン

plugins {
    id 'java'
    id 'war'
}

dependenciesに compileOnly 'javax:javaee-api:8.0' を追加

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compileOnly 'javax:javaee-api:8.0'
}

war関係の設定をしたい場合warブロックを作成してその中に設定を書き込んでいきます。
今回はwarにビルドしたときの名前だけ変更するようにしましょう

war {
    archiveName = 'app.war'
}

ここまでで一旦build.gradleをsync

ServletJSPを作成

適当なServletと、そこにgetしたらWEB-INF以下のjspにアクセスするように書いてみます。

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/example")
public class ExampleServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(req, resp);
    }
}

次にWEB-INFなどを格納するフォルダを作成するわけですが、warプラグインのデフォルトではsrc/main/webapp以下を見るようになっているので、今回はそこに作成していきます。他のディレクトリを設定したい場合は先程のサイトを参考にwarの設定を変えてください。

  • src/main/webapp/WEB-INF/jsp/example.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Title</title>
</head>
<body>
  <h1>Hello!</h1>
</body>
</html>

ビルドする

とりあえずここまでで一旦ビルドしてwarファイルを出力してみます。
Run > Edit Configurationsから左上の+を押しGradleを追加。
NameはCompileWarとかわかり易い名前にしておきます。
gradle projectのフォルダマークを押せばこのプロジェクトがサジェストされると思うのでそれを選択。
あとはTasksにclean warとだけ書いて保存してください。
実際に実行してみてbuild/libs配下にwarファイルが生成できていたら大丈夫です。

Tomcatコンテナを建てる

Run > Edit Configurationsを選んで左上の+を押しDocker > Docker Imageを追加します。
NameはDockerRunなどわかり易い名前に。
Serverは先程作成したコネクション設定で。
Image IDは好きなtomcatのイメージを、今回はtomcat:8.5.41-jdk8としておきましょう。
Container nameは自分が管理しやすい名前を設定してください。
Bind portsは自分が使いやすい用にしてください。今回は8080:8080に。
最後にBind mountsを設定します。
Host pathを先程warファイルが出力されていたlibsフォルダに、Container pathを/usr/local/tomcat/webappsに設定します。
あとは保存して右上のタスクからDockerRunを選択し実行するだけです。
正しく設定できていればImageをダウンロードしてコンテナが建てられていると思います。

自動デプロイ

logが流れてtomcatが起動したのを確認したらhttp://localhost:8080/app/exampleに接続してみます。最初のパス(app)はarchiveNameで設定した名前です。
無事に接続できていれば、後はRunで先程設定したCompileWarのタスクを実行するようにしてやれば数秒後に自動でデプロイされて確認できます。
お疲れ様でした。