Tomcatのインストールと自動起動の設定

# はじめに

# 使用した環境

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

# Javaのインストール

* Javaは[こちらのページ](https://aws.amazon.com/jp/corretto/)のリンク先から、Amazon Corretto8をダウンロードしました。
* Amazon CorrettoはRPM形式が選択できるため、パッケージ管理がしやすい`yum`コマンドでインストールしています。

```shell-session
[root@akagi ~]# yum install -y https://corretto.aws/downloads/latest/amazon-corretto-8-x64-linux-jdk.rpm
[root@akagi ~]# java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment Corretto-8.242.08.1 (build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM Corretto-8.242.08.1 (build 25.242-b08, mixed mode)
```

# Tomcatのインストール

* Tomcatは[こちらのページ](http://tomcat.apache.org/)のリンク先から、Tomcat9.0をダウンロードしました。
 * JavaとTomcatのバージョンの対応関係については、[こちらのページの対応表](https://openstandia.jp/oss_info/tomcat/)が分かりやすいです。
 * `yum`コマンドでTomcatをインストールすることも出来ますが、Tomcatのバージョンが7.0とかなり古いため、今回はTomcatの公式サイトからダウンロードしました。
* Tomcatはzip形式やtar.gz形式しか選べないため、tar.gzでダウンロードしたものを所定のフォルダに配置してから展開してインストールしています。
* 最後に`startup.sh`と`shutdown.sh`を使って、Tomcatを正常に起動/停止できることを確認します。

```shell-session:Tomcatのインストール
[root@akagi ~]# wget https://www-eu.apache.org/dist/tomcat/tomcat-9/v9.0.30/bin/apache-tomcat-9.0.30.tar.gz
[root@akagi ~]# mv apache-tomcat-9.0.30.tar.gz /usr/local/
[root@akagi ~]# cd /usr/local/
[root@akagi local]# tar zxvf apache-tomcat-9.0.30.tar.gz 
[root@akagi local]# ls
apache-tomcat-9.0.30         bin  games    lib    libexec  share
apache-tomcat-9.0.30.tar.gz  etc  include  lib64  sbin     src
```
```shell-session:Tomcatの起動と停止
[root@akagi local]# sh ./apache-tomcat-9.0.30/bin/startup.sh
Using CATALINA_BASE:   /usr/local/apache-tomcat-9.0.30
Using CATALINA_HOME:   /usr/local/apache-tomcat-9.0.30
Using CATALINA_TMPDIR: /usr/local/apache-tomcat-9.0.30/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/apache-tomcat-9.0.30/bin/bootstrap.jar:/usr/local/apache-tomcat-9.0.30/bin/tomcat-juli.jar
Tomcat started.
[root@akagi local]# sh ./apache-tomcat-9.0.30/bin/shutdown.sh 
Using CATALINA_BASE:   /usr/local/apache-tomcat-9.0.30
Using CATALINA_HOME:   /usr/local/apache-tomcat-9.0.30
Using CATALINA_TMPDIR: /usr/local/apache-tomcat-9.0.30/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /usr/local/apache-tomcat-9.0.30/bin/bootstrap.jar:/usr/local/apache-tomcat-9.0.30/bin/tomcat-juli.jar
```

# Tomcatの自動起動の設定

## シンボリックリンクの追加

* Tomcat9のインストールフォルダに対して、tomcat9というシンボリックリンクを付けます。
* シンボリックリンクを付けておくことにより、例えばTomcatのバージョンを上げた場合にもシンボリックリンクの修正だけで済むため、後述するユニットファイルを修正せずに済みます。

```shell-session:シンボリックリンクの追加
[root@akagi local]# ln -s apache-tomcat-9.0.30 tomcat9
[root@akagi local]# ls -l | grep tomcat9
lrwxrwxrwx  1 root root       20  2月  2 13:40 tomcat9 -> apache-tomcat-9.0.30
```

## Tomcatユーザーの作成

* Tomcatを自動起動する際に利用する`tomcat`というユーザーを作成します。
* この時、tomcatユーザーにはホームディレクトリは不要なので、`useradd`コマンドに`-M`オプションを付けています。

```shell-session:Tomcatユーザーの作成
[root@akagi local]# useradd -M tomcat
[root@akagi local]# id tomcat
uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat)
```

## フォルダのパーミッション変更

* 先程に作成した`tomcat`ユーザーがTomcatを起動できるように、Tomcatのインストールフォルダ以下の権限を変えておきます。

```shell-session:フォルダのパーミッション変更
[root@akagi local]# chown tomcat:tomcat -R ./tomcat9/
[root@akagi local]# ls -l | grep tomcat
drwxr-xr-x  9 tomcat tomcat      220  1月 26 22:04 apache-tomcat-9.0.30
-rw-r--r--  1 root   root   11026056 12月  8 02:16 apache-tomcat-9.0.30.tar.gz
lrwxrwxrwx  1 root   root         20  2月  2 13:40 tomcat9 -> apache-tomcat-9.0.30
```

## ユニットファイルの作成

* `tomcat9.service`という名前で、systemd用の`ユニットファイル`を作成します。
 * CentOS6系までははchkconfigを利用していましたが、CentOS7系からはsystemdという仕組みを使って自動起動を実現するのが一般的なようです。


```text:tomcat9.service
[Unit]
Description=Apache Tomcat 9.0.30
ConditionPathExists=/usr/local/tomcat9

[Service]
User=tomcat
Group=tomcat
Type=oneshot

ExecStart=/usr/local/tomcat9/bin/startup.sh
ExecStop=/usr/local/tomcat9/bin/shutdown.sh
Restart=no
RemainAfterExit=yes

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

* ユニットファイルの項目については、以下のサイトなどが参考になりました。
 * [10.6. SYSTEMD のユニットファイルの作成および変更 - RedHatの公式リファレンス](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files)
 * [Systemd入門(4) - serviceタイプUnitの設定ファイル](http://enakai00.hatenablog.com/entry/20130917/1379374797)
 * [Systemd メモ書き](https://qiita.com/a_yasui/items/f2d8b57aa616e523ede4)
 * [systemdの*.serviceファイルの書き方](https://qiita.com/masami256/items/ef0f23125cf8255e4857)
 * [systemdを用いたプログラムの自動起動](https://qiita.com/tkato/items/6a227e7c2c2bde19521c)

|セクション|オプション|説明|
|---|---|---|
|Unit|Description|このサービスを示す説明文。|
|Unit|ConditionPathExists|ユニットが開始する前に、ここで指定した絶対パス名が存在するかをチェックする。|
|Service|User|サービスを起動するユーザー。|
|Service|Group|サービスを起動するグループ。|
|Service|Type|サービスの起動完了の確認方法。デフォルト値の`simple`は、プロセスが起動した時点で起動完了とみなす。`oneshot`は一度だけ実行するサービスに用いる。|
|Service|ExecStart|サービスを起動するコマンド。|
|Service|ExecStop|サービスを停止するコマンド。|
|Service|Restart|サービス停止時の再起動条件。デフォルト値は`no`。|
|Service|RemainAfterExit|プロセス起動後もステータスがActiveのままとなる。`Type=oneshot`の時に有用。|
|Install|WantedBy|自動起動を有効化する「ランレベル」に相当する設定。`multi-user.target`はランレベル3に相当。|

## ユニットファイルの配置

* 作成した`tomcat9.service`を、`/etc/systemd/system/`以下に配置して、Tomcatが自動的に起動するように設定します。
* `systemctl list-unit-files...`の結果が`disabled`ではなく`bad`となっている場合は、下記の点を見直してください。
 * ファイルの権限：私は`/etc/systemd/system/`以下の他のファイルやディレクトリに合わせて755を付与しました。
 * 構文エラー：`[`が`{`になっていたりすると、badとなってしまいます。

```shell-session:ユニットファイルの配置
[root@akagi ~]# chmod 755 tomcat9.service 
[root@akagi ~]# cp -a tomcat9.service /etc/systemd/system/
[root@akagi ~]# systemctl daemon-reload
[root@akagi ~]# systemctl list-unit-files --type=service | grep tomcat
tomcat9.service                               disabled
```

## 自動起動の設定

* `systemctl enable...`で自動起動の設定をして、最後に自動起動設定を確認すれば完了です。

```shell-session:自動起動の設定
[root@akagi ~]# systemctl enable tomcat9
Created symlink from /etc/systemd/system/multi-user.target.wants/tomcat9.service to /etc/systemd/system/tomcat9.service.
[root@akagi ~]# systemctl list-unit-files -t service | grep tomcat9
tomcat9.service                               enabled 
```

# 関連記事

* [ApacheとTomcatを連携させる](https://qiita.com/nkojima/items/7a8dd5c5e1d3c032178c)
 * ApacheからリバースプロキシでTomcatにリクエストを投げる方法をまとめました。