ApacheとTomcatを連携させる

# はじめに

[Tomcatのインストールと自動起動の設定](https://qiita.com/nkojima/items/cb9e2056ae532c8dd0dc)の続きとして、Apache側で受け取ったHTTPリクエストをTomcatに投げる設定をまとめてみました。

# 使用した環境

* OS
 * CentOS 7.7（1908）
* Java（Amazon Corretto）
 * Java 1.8.0_242
* Apache
 * Apache-2.4.6
* Tomcat
 * Tomcat-9.0.30

# 連携のイメージ

* 以下の図のように、クライアントからのリクエストをApacheが受けた後、Apacheのリバースプロキシ機能を使ってTomcatにリクエストを投げます。
* ApacheとTomcatの連携に`mod_proxy_ajp`を使う場合はAJPプロトコル、`mod_proxy_http`を使う場合はHTTPプロトコルで繋がります。

```
+-------------+  HTTP/HTTPS  +--------+  HTTP/AJP  +--------+
| クライアント | -----------> | Apache | ---------> | Tomcat |
+-------------+              +--------+            +--------+
```


# Apacheのインストール

* yumコマンドでインストールした後、バージョン情報を表示して正しくインストールされたことを確認しておきます。

```shell-session
[root@akagi ~]# yum install -y httpd
[root@akagi ~]# httpd -v
Server version: Apache/2.4.6 (CentOS)
Server built:   Aug  8 2019 11:41:18
```

# Apacheの自動起動の設定

* systemctl enable...で自動起動の設定をして、その後に自動起動設定を確認しておきます。

```shell-session
[root@akagi ~]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@akagi ~]# systemctl list-unit-files -t service | grep httpd
httpd.service                                 enabled 
```

# 設定ファイルの編集

* ここではhttpd.confを編集して、ApacheからTomcatへリバースプロキシでリクエストを投げる設定をします。

## /etc/httpd/conf.modules.d/00-proxy.confの確認

* `/etc/httpd/conf.modules.d/00-proxy.conf`にはリバースプロキシに使われるモジュールの設定が記載されています。
* `mod_proxy.so`と`mod_proxy_ajp.so`が記載されており、コメント行になっていないことを確認します。
 * 行頭が`#`だとコメント行になります。
* `mod_proxy_ajp`を使うと、HTTPよりも効率の良いAJPというプロトコルを使ってTomcatと通信することができます。
 * かなり前は`mod_jk`や`mod_jk2`というモジュールを使っていたと思うのですが、いつの間にか使用するモジュールが変わっていました...

```shell-session:00-proxy.conf
# This file configures all the proxy modules:
LoadModule proxy_module modules/mod_proxy.so
...
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
...
```

## httpd.confのバックアップ

* httpd.confを編集する前に、オリジナルの状態でhttpd.confをバックアップしておきます。

```shell-session
[root@akagi ~]# cd /etc/httpd/conf/
[root@akagi conf]# cp -a httpd.conf httpd.conf.org
```

## リバースプロキシの設定

* ProxyPassおよびProxyPassReverseを以下の要領で設定します。
 * `ProxyPass {リクエストパス} ajp://localhost:8009/{Javaアプリのコンテキスト名}`
 * `ProxyPassReverse {リクエストパス} ajp://localhost:8009/{Javaアプリのコンテキスト名}`
* ProxyPassとProxyPassReverseはいずれも「リクエストパスに来たリクエストを、アプリケーションサーバー（※ここではTomcat）に転送する」という役割を持ちますが、リダイレクトを使う場合はProxyPassReverseを設定しておく必要があります。
 * 以下の例では、リクエストが`http://{サーバーのIP}/tomcat9/`にマッチする場合、自ホスト（localhost）の8009番ポートのコンテキスト名`/`（※Tomcatの管理画面）に転送する設定となっています。
 * 参考URL：[mod_proxy再入門 – ProxyPassとProxyPassReverse](https://dev.classmethod.jp/server-side/server/introduction_mod_proxy/)

```shell-session:/etc/httpd/conf/httpd.conf
# 以下をファイルの末尾に追記
ProxyPass /tomcat9/ ajp://localhost:8009/
ProxyPassReverse /tomcat9/ ajp://localhost:8009/
```

* 例えば、Tomcat上で動作しているコンテキスト名が`test`のアプリに対してリバースプロキシの設定をする場合は、以下のような設定になります。
 * `tomcat9`としている箇所は、任意の文字列に置き換え可能です。

```shell-session:/etc/httpd/conf/httpd.conf
# 以下をファイルの末尾に追記
ProxyPass /tomcat9/ ajp://localhost:8009/test/
ProxyPassReverse /tomcat9/ ajp://localhost:8009/test/
```


# 設定の反映

* CentOS5系およびCentOS6系では`service httpd graceful`を実行して、Apacheを強制的に再起動させるのではなく、設定値の反映だけをさせてきましたが、CentOS7系のApacheだと`graceful`が使えません。
* [こちらの記事](https://bacchi.me/linux/tips-3/)によると、`reload`を使って`systemctl reload httpd`を実行すれば、従来の`graceful`と同じ効果が得られるそうです。

```shell-session
[root@akagi ~]# systemctl reload httpd
```

# 動作の確認

* 最後に`http://{サーバーのIP}/tomcat9/`にアクセスして、Tomcatの管理画面が見られることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312166/af8aa93e-79e9-cf46-825d-9ae811013960.png)

# 関連する作業

* [Tomcatの8080番ポートを塞ぐ](https://www.adminweb.jp/apache/tomcat/index2.html)
* [ApacheでIPアドレスによるアクセスを禁止する](https://qiita.com/nkojima/items/38726b421be223c4b61a)