App Service にて Tomcat の設定ファイルを変更してカスタムエラーページを構成する方法

# はじめに
[Microsoft Azure Tech Advent Calendar 2021](https://qiita.com/advent-calendar/2021/microsoft-azure-tech "Microsoft Azure Tech Advent Calendar 2021") の 2 日目の記事です。本稿では、App Service を Tomcat で運用する上で知っていると役立つ Tips を紹介します。

[App Service](https://docs.microsoft.com/ja-jp/azure/app-service/overview "App Service の概要") は Windows、Linux、Docker コンテナ（カスタム コンテナー）の Web アプリケーションを Azure 上にホストすることができる PaaS です。Java/Tomcat をスタックとする App Service のリソースを作成する方法については当記事では割愛するため、[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/app-service/quickstart-java?tabs=javase&pivots=platform-linux "クイック スタート:Azure App Service で Java アプリを作成する")等をご確認くださいませ。

# 概要
App Service では Java アプリケーションのランタイムの一つとして Tomcat を選択することが可能です。App Service が稼働する上で必要な Tomcat のバイナリや設定ファイルは有難いことに予め Azure により提供されています。そのため、基本的には自分たちで Tomcat の設定を構成せずとも Java アプリケーションを App Service で運用することが可能です。

しかしながら、状況に応じて Tomcat の設定をデフォルトから変更したい場合があるかと思います。当記事では、Tomcat の設定にてカスタムエラーページを構成したい場合に役立つ Tips をご紹介します。（今回の記事では、Windows 版の App Service で Tomcat 9.0.38 を使用している環境を例に解説します。）


# Tomcat の設定ファイル (conf 配下) を変更する方法
デフォルトの設定では Tomcat の コンフィグレーションを含む設定ファイルは、現時点では C:\Program Files\apache-tomcat-9.0.38 配下に配置されています。（ホームドライブは C ではなく D の場合もあります。） しかしながら、こちらのディレクトリ配下のファイルは App Service の制約により変更がサポートされておりません。この問題を解決するには C:\home 配下に任意のフォルダを作成し、このフォルダ配下に作成した設定ファイルを [CATALINA_BASE](https://tomcat.apache.org/tomcat-9.0-doc/introduction.html "CATALINA_BASE") の指定にて参照させる必要があります。このようにして、CATALINA_BASE は Tomcat の実行用バイナリファイルと設定ファイルを別のフォルダで管理することを可能とします。

## 具体的な手順
1. Kudu（高度なツール）の Debug Console より、C:\home 配下にて tomcat フォルダを作成します。

2. デフォルトの設定ファイルを C:\home\tomcat にコピーします。 
 cp -r "C:\Program Files\apache-tomcat-9.0.38\conf" C:\home\tomcat\conf

3. C:\home\tomcat\ 直下に logs, work, temp ディレクトリを作成します。

4. C:\home\tomcat\conf\ 配下の設定ファイル (server.xml 等) に任意の修正を行います。

5. 該当の App Service のポータルにて、[構成]メニューよりアプリケーション設定に以下の設定を追加します。(App Service の再起動が発生します)

    名前: CATALINA_BASE
    値: C:\home\tomcat

# 設定ファイルの変更を必要とする例
## Tomcat のデフォルトのエラーページの代わりにカスタムエラーページを表示させる
App Service への HTTP リクエストに対するレスポンスとして HTTP ステータスコードが 400 もしくは 500 番台を返却する場合、基本的には App Service にホストしているアプリケーションの Web フレームワーク等によりエラーページをブラウザに返却させる場合が多いかと思います。しかしながら 400番台のエラーにおいては Tomcat のリクエスト処理が行われるパイプラインの入り口にて Tomcat 自体がエラーを返却する場合があるため、このような状況では HTTP リクエストが Web アプリケーション自体に到達せず、Tomcat のデフォルトのエラーページが表示されます。任意のエラーページを表示させるには、以下のように Tomcat の設定を行うことで実現が可能です。

### 手順
※前述の手順により C:\home\tomcat\ 配下の設定ファイルが参照される前提で解説します。

#### 1. C:\home\tomcat\server.xml の HOST タグ内に以下の定義を入れます。
以下ではエラーコード400に対応したカスタムエラーページを表示する設定を定義しています。他のエラーコード以外の定義も可能なので、必要に応じて同様の定義を追加ください。（errorCode=0は、server.xmlに定義が無いエラーコードの場合に表示するカスタムエラーページを定義します。）

```
<Valve className="org.apache.catalina.valves.ErrorReportValve"
                errorCode.400="C:\home\site\wwwroot\webapps\ROOT\error400.html"
                errorCode.0="C:\home\site\wwwroot\webapps\ROOT\errorOthers.html"
                showReport="false"
                showServerInfo="false" />
```
server.xml に追加する ErrorReportValve に関する詳細は以下の Tomcat のドキュメントが参考になります。

■Apache Tomcat 9 Configuration Reference
http://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#Error_Report_Valve
※Error Report Valve の項をご参照ください


#### 2. カスタムエラーページの HTML ファイルを以下のファイルパスで作成します。
(1) 400エラー用
```  C:\home\site\wwwroot\webapps\ROOT\error400.html```
(2) errorCode.0用（※任意。エラーコードの定義が server.xml に無い HTTP エラー用。）
```C:\home\site\wwwroot\webapps\ROOT\errorOthers.html```

#### 3. App Service を再起動します。
エラーページの反映が確認できない場合は、ブラウザキャッシュのクリアをお試しください。


# App Service 上で Tomcat の設定を変更する際に行ってはいけないこと
## Tomcat のバージョン自動更新を有効にしてはいけない
App Service においては Tomcat のバイナリ (CATALINA_HOME) と設定ファイル (CATALINA_BASE) に対して、App Service 上で Tomcat を動作させるためのカスタマイズがデフォルトで行われています。Tomcat のバージョンが App Service のアップデートにて上がった場合に CATALINA_BASE で独自の設定を参照している場合は CATALINA_HOME に存在するバイナリのみがバージョンアップすることから、両者の整合性が取れずに問題が生じる可能性があります。その為、Tomcat のバージョン自動更新により不意に問題が発生することを避けるためには以下のように特定のバージョンを固定で指定する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245530/06cd95a8-dbdc-5cc2-b0db-6951b00a313e.png)

# 最後に
以上のような方法で Tomcat の設定をカスタマイズすることが可能です。Tomcat のバージョンを固定している場合は上記のような方法で Tomcat の設定を変更できるので、こちらの方法が参考になればと思います。