Apache+Tomcat8をセットアップする

# 環境

OS: CentOS 7.6.1810
<details><summary>Vagrantfile</summary><div>

```ruby:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.provider "virtualbox" do |vb|
    vb.cpus = 2
    vb.memory = "8192"
  end
  config.vm.network :forwarded_port, guest: 9000, host: 9000
  config.vm.network :forwarded_port, guest: 9010, host: 9010
  config.vm.synced_folder "share/", "/share", owner: "vagrant", group: "vagrant"
end
```
</div>
</details>

* SELinuxは`disabled`にしておく。
* Apache, OpenJDKはrpm、Tomcatは公式のバイナリを利用する。
* Apache-Tomcat間はmod_jkを利用する。


# セットアップ手順
## Tomcat

OpenJDKのインストール。

```shell-session
# yum -y install java-1.8.0-openjdk
```

tomcatユーザの作成。

```shell-session
# groupadd tomcat
# useradd -g tomcat -M -d /opt/tomcat -s /bin/nologin tomcat
# id tomcat
uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat)
```

[Tomcat8のダウンロードページ](https://tomcat.apache.org/download-80.cgi)からURLを確認し、バイナリファイルをミラーサイトから取得して展開。
設定ファイル作成時にバージョン指定が面倒なのでsymlinkも作成。

```shell-session
# cd /tmp
# curl -s -O http://us.mirrors.quenda.co/apache/tomcat/tomcat-8/v8.5.40/bin/apache-tomcat-8.5.40.tar.gz
# cd /opt
# tar zxf /tmp/apache-tomcat-8.5.40.tar.gz
# chown -R tomcat:tomcat apache-tomcat-8.5.40
# ln -sfn apache-tomcat-8.5.40 tomcat && ls -l /opt
total 0
drwxr-xr-x. 9 tomcat tomcat 220 Apr 21 02:05 apache-tomcat-8.5.40
lrwxrwxrwx. 1 root   root    20 Apr 21 02:06 tomcat -> apache-tomcat-8.5.40
```

PIDFileの保存先の作成（次回起動時の生成も定義しておく）。

```
# install -d -m 0710 -o tomcat -g tomcat /run/tomcat
# ls -ld /run/tomcat
drwx--x---. 2 tomcat tomcat 40 Apr 21 02:35 /run/tomcat

# cat <<EOS > /etc/tmpfiles.d/tomcat.conf
d /run/tomcat           0710    tomcat   tomcat
EOS
```

環境変数定義ファイルの作成。

```bash:/etc/sysconfig/tomcat
JAVA_HOME="/usr/lib/jvm/jre"
CATALINA_PID="/run/tomcat/tomcat.pid"
CATALINA_HOME="/opt/tomcat"
CATALINA_BASE="/opt/tomcat"
CATALINA_OPTS="-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
```

Unitファイルの作成。

```ini:/etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target

[Service]
User=tomcat
Group=tomcat
Type=forking
EnvironmentFile=/etc/sysconfig/tomcat
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target
```

起動/停止確認。

```shell-session
# systemctl enable tomcat.service
# systemctl start tomcat.service
# systemctl status tomcat.service
● tomcat.service - Apache Tomcat Web Application Container
   Loaded: loaded (/etc/systemd/system/tomcat.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2019-04-21 03:55:03 UTC; 1s ago
  Process: 31997 ExecStart=/opt/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 32005 (java)
   CGroup: /system.slice/tomcat.service
           └─32005 /usr/lib/jvm/jre/bin/java -Djava.util.logging.config.file=
...
// active (running)になっていること

# cat /run/tomcat/tomcat.pid
32005
// ファイルが存在してsystemdが認識しているPIDが記録されていること

# ss -nltp | grep java
// 8005/tcp, 8080/tcp, 8009/tcpをLISTENしていること

# curl -s http://127.0.0.1:8080/
// アクセスできること

# systemctl stop tomcat.service
# systemctl status tomcat.service
● tomcat.service - Apache Tomcat Web Application Container
   Loaded: loaded (/etc/systemd/system/tomcat.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
// inactive (dead)になっていること
// 停止時にエラー等出ていないこと
```

Listen Portの変更。

* 8005/tcp: tomcat停止用（セキュリティを考慮するならshutdownフレーズも要変更）。
* 8080/tcp: tomcatへの直接アクセス用なので無効化。
* 8009/tcp: Apache連携用。SSLは利用しないのでredirectPortは削除。

```diff:/opt/tomcat/conf/server.xml
-<Server port="8005" shutdown="SHUTDOWN">
+<Server port="9005" shutdown="SHUTDOWN">

+    <!--
     <Connector port="8080" protocol="HTTP/1.1"
                connectionTimeout="20000"
                redirectPort="8443" />
+    -->

-    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
+    <Connector port="9001" protocol="AJP/1.3" />
```

ポートの変更確認。

```shell-session
# systemctl start tomcat.service
# ss -nltp | grep java
// 9001/tcp, 9005/tcpをLISTENしていること
```

## Apache with mod_jk

Apacheのインストール（mod_jkのビルドに必要なのでhttpd-develも）。

```shell-session
# yum -y install httpd httpd-devel
```

[Tomcat Connectorsのダウンロードページ](http://tomcat.apache.org/download-connectors.cgi)からURLを確認し、Sourceパッケージをダウンロードして展開。

```shell-session
# cd /tmp
# curl -s -O https://www-eu.apache.org/dist/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.46-src.tar.gz
# tar zxf tomcat-connectors-1.2.46-src.tar.gz
# cd tomcat-connectors-1.2.46-src/native
```

apxsのパスを確認してビルド。

```shell-session
# which apxs
/bin/apxs

# ./configure --with-apxs=/bin/apxs
# make && make install
...
Libraries have been installed in:
   /usr/lib64/httpd/modules
...

# ls -l /usr/lib64/httpd/modules/mod_jk.so
-rwxr-xr-x. 1 root root 1556792 Apr 21 04:56 /usr/lib64/httpd/modules/mod_jk.so
```

mod_jkを利用するconfigの作成（`ServerRoot`を/etc/httpdとした場合）。
参考: [24.7. Apache mod_jk HTTP Connector](https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.2/html/configuration_guide/configuring_high_availability#mod_jk-config)

```conf:/etc/httpd/conf.d/mod_jk.conf
# Load mod_jk module
LoadModule jk_module modules/mod_jk.so

# Where to find workers.properties
JkWorkersFile conf.d/workers.properties

# Where to put jk logs
JkLogFile logs/mod_jk.log

# Set the jk log level [debug/error/info]
JkLogLevel info

# Select the log format
JkLogStampFormat  "[%a %b %d %H:%M:%S %Y]"

# JkOptions indicates to send SSK KEY SIZE
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat
JkRequestLogFormat "%w %V %T"

# Mount your applications
JkMount /examples/* lb

# Add shared memory.
# This directive is present with 1.2.10 and
# later versions of mod_jk, and is needed for
# for load balancing to work properly
JkShmFile logs/jk.shm

# Add jkstatus for managing runtime data
<Location /jkstatus/>
    JkMount status
    Require ip 127.0.0.1
</Location>
```

```properties:/etc/httpd/conf.d/workers.properties
# Define list of workers that will be used for mapping requests
worker.list=lb,status

# Define Node1
worker.node1.type=ajp13
worker.node1.host=127.0.0.1
worker.node1.port=9001
worker.node1.ping_mode=A
worker.node1.lbfactor=1

# Define Load-balancer
worker.lb.type=lb
worker.lb.balance_workers=node1
worker.lb.sticky_session=1

# Status worker for managing load balancer
worker.status.type=status
```

httpd.confの修正。

```diff:/etc/httpd/conf/httpd.conf
-Listen 80
+Listen 9000

 ServerAdmin root@localhost
+ServerName  localhost

-IncludeOptional conf.d/*.conf
+Include conf.d/mod_jk.conf
```

SyntaxチェックしてApacheを起動。

```
# apachectl configtest
Syntax OK
// Syntax OK になること

# systemctl start httpd.service
# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2019-04-21 05:30:43 UTC; 1min ago
...
// active (running) になること

# ss -nltp | grep httpd
// 9000/tcpをListenしていること
```

## 確認

http://127.0.0.1:9000/examples にアクセスしてTomcatのサンプルページが表示されること。