VSCode+Tomcat+DockerでJSP/Servlet開発環境構築

# 経緯

使っているMac環境が汚くなり、初期化

↓

そして、Docker(触るの初めて)でTomcat(触るの初めて)環境をつくって
JSP/Servlet(触るの初めて)でWEBアプリケーション作成しよう

↓

エディターはVisualStudioCodeを前から使っていたので、
それで環境構築してやろう

とした際、ドハマリしたので記録を残します。
(誰かの参考になるとうれしい、、)

# 環境
- MacOS Monterey(Intel) (執筆時最新)
- Docker 20.10.12 (執筆時最新)
- Tomcat10.1.0-M11 & JDK17 & Debian bullseye(11)
(公式のDockerイメージ`tomcat:10.1.0-jdk17`を利用)
- Visual Studio Code 1.65.2 (執筆時最新)

基本的にどれも執筆時最新バージョンを使っています。

# 手順
1. VSCode・Homebrewインストール
1. Dockerインストール
1. VSCode拡張機能インストール
1. ディレクトリ・ファイル作成
1. コンテナ作成・起動(リモート接続)

# VSCode・Homebrewインストール
どちらも公式から。

## VSCode

https://azure.microsoft.com/ja-jp/products/visual-studio-code/

(ダウンロードしたものをアプリケーションフォルダに入れると便利です)

## Homebrew

https://brew.sh/index_ja

(ターミナル.appを開いてコマンドを貼っつけてReturn)

インストール後に以下のコマンドで確認
```
% brew -v
```

:::note info
もしかしたらHomebrewをインストールするときに
`Command Line Tools for XCode`のインストールが必要かもしれないです
:::


# Dockerインストール
ターミナル.appより以下を**順に実行**
[ハマったところ その1](https://qiita.com/suzukiti/items/391bfce352ba94ad3f0d#docker-desktop%E3%81%8C%E5%85%A5%E3%82%89%E3%81%AA%E3%81%84)
```
% brew install --cask docker
% brew install docker
```
アプリケーションのDocker.appを開く

以下で確認
```
% docker --version
```

# VSCode拡張機能インストール
## Remote - Containers
ざっくりと
- Dockerコンテナの作成・起動等の管理
- ローカルのディレクトリをDockerにマウント

できるモノです
(他にももっといろいろできます)

VSCode立ち上げ、左の「拡張機能」のアイコンからインストール


# ディレクトリ・ファイル作成
**ここからが本題です**

ディレクトリを作成し、以下のように配置します。
配置場所は任意(どこでもいい)です。
```
hello/
└── .devcontainer/
    ├── devcontainer.json
    └── tomcat-docker
```

そして、ファイルを編集していきます。

```json:devcontainer.json
{
  # 任意
  "name": "hello",

  # コンテナ作成のためのDockerfileの名称を指定。今回はtomcat-docker。
  "dockerFile": "tomcat-docker",

  # ホストOSの8080宛の通信をコンテナの8080に転送
  "forwardPorts": [8080],

  # コンテナに入ったときのカレントディレクトリを指定
  "workspaceFolder": "/usr/local/tomcat",

  # ホストOSのVSCodeのプロジェクト直下のディレクトリを
  # コンテナの/usr/local/tomcat/webapps/hogeにマウント
  "mounts": [
    "source=${localWorkspaceFolder},target=/usr/local/tomcat/webapps/hoge,type=bind,consistency=cached"
  ],

  # コンテナ生成時に、コンテナにインストールする拡張機能
  # 指定しないと、コンテナが再生成すると拡張機能が消えます。
  # 今回はJava Extension Packをインストール
  "extensions": [
    "vscjava.vscode-java-pack"
  ]
}
```

```text:tomcat-docker
# Tomcatイメージをダウンロード
FROM tomcat:10.1.0-jdk17

# 下記補足にて
RUN rm -r /usr/local/tomcat/webapps
RUN mv /usr/local/tomcat/webapps.dist /usr/local/tomcat/webapps

# ローカルのソースコードのマウントするディレクトリを作成
RUN mkdir /usr/local/tomcat/webapps/hoge
```

:::note info
補足
Dockerの公式Tomcatイメージではセキュリティ勧告により、
Webアプリ例は`webapps.dist`に格納されています。
そして、既存のWebappsディレクトリは空になっています。
ですので、Dockerfileにてそれを削除し、.distを名称変更しています。
:::

以下ソース

https://github.com/docker-library/docs/blob/master/tomcat/README.md#how-to-use-this-image

> ```text:翻訳
> 注意: docker-library/tomcat#181の時点では、上流が提供する（例の）ウェブアプリは、
> 上流のセキュリティ勧告によりデフォルトでは有効になっていませんが、
> 再有効化を容易にするため、イメージ内のwebapps.distフォルダで利用可能です。
> ```

# コンテナ作成・起動(リモート接続)

1. VSCodeの左下隅に`><`みたいなマークがあるので選択
1. `Open Folder in Container..`を選択
1. 先程作成したディレクトリを選択 (`hello/`ディレクトリ)
1. ビルドが走ります。ちょっと待ちましょう。[ハマったところ その2](https://qiita.com/suzukiti/items/391bfce352ba94ad3f0d#%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E3%81%AB%E5%A4%B1%E6%95%97%E3%81%99%E3%82%8B)
1. `Control+Shift+^`でターミナルを起動

ちゃんと入れていれば以下コマンドを打つとversionが出力されるはずです。
```
# version.sh
# java --version
```
Tomcatを起動
```
# startup.sh
```

ローカルのブラウザから
http://localhost:8080/
に接続すると成功した旨の表示がされるはずです！

再起動は
```
# shutdown.sh
# startup.sh
```
でできます！
(もっとスマートな方法はないのかな..)

### そして開発へ
例えば`/usr/local/tomcat/webapps/hoge/a.html`を作成し、
http://localhost:8080/hoge/a.html
に接続するとページが表示されるはずです
[ハマったところ その3](https://qiita.com/suzukiti/items/391bfce352ba94ad3f0d#%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BDtomcat-for-java%E3%81%A7%E3%81%AF%E6%8E%A5%E7%B6%9A%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84)

# ハマったところ
## Docker Desktopが入らない
Dockerインストール時に、`brew install --cask docker`すると
エラってDocker Desktopが入りませんでした。
これは**先に`brew install docker`してた**からみたいでした。
なので、一旦`brew uninstall docker`してcaskを先にinstallすれば
すんなり入りました。
(もしかすると、そのあとのcaskなしインストールは不要かもしれない..)
根本原因はわかってません。。

## コンテナのビルドに失敗する
コンテナ作成・起動の際に、ビルドが失敗することがありました。
これは単純に、インターネットに接続されていないことが原因でした。
ネットに繋ぐとうまくいきました。

## 拡張機能tomcat for javaでは接続できない
これが一番ハマりました。。
はじめ、コンテナに`拡張機能tomcat for java`を入れて
Tomcatを立ち上げてました。
しかし、`/usr/local/tomcat/webapps/hoge/a.html`を作成して、
`http://localhost:8080/hoge/a.html`に接続しても404表示。。
どうやらこの拡張機能、**warファイルにしか対応していない**みたいです。
なので、これを入れずに、コマンドで立ち上げると正常に表示されました。

(追記)
自分はwarファイルを作らずに、接続しようとしたため、404表示されたみたいです。
すなわち、Tomcat for javaではwarファイルを作らないと接続できないみたいです。

# さいごに
初めての記事で拙いところがあるかもです。。
間違い等あれば、指摘いただけると幸いです！

# 参考
https://tech-lab.sios.jp/archives/18917
https://language-and-engineering.hatenablog.jp/entry/20120904/LearnTomcatServletJSP

p.s.
なんでも、初めてやるときが一番大変で、とにかくハマりまくります。
そういうときにいつも、「まだまだだな、もっと勉強しなくては」と
実感します。。