Tomcat 10をJava 21で動かす

UbuntuにTomcat 10をインストールしJava 21で動かしたいが、まだパッケージでは提供されていないため、手動でインストールする。

前提

Java 21がインストール済みであること。
インストールされていない場合はこちらの記事の「Java 21のインストール」を参照のこと。

$ java -version
openjdk version "21" 2023-09-19 LTS
OpenJDK Runtime Environment Temurin-21+35 (build 21+35-LTS)
OpenJDK 64-Bit Server VM Temurin-21+35 (build 21+35-LTS, mixed mode, sharing)

Tomcat 10のインストール

Apache Tomcatのページがら最新版をダウンロードして解凍する。今後のため、シンボリックリンクも作成しておく。

$ wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.15/bin/apache-tomcat-10.1.15.tar.gz
$ tar -xvf apache-tomcat-10.1.15.tar.gz
$ sudo ln -s /opt/apache-tomcat-10.1.15 /opt/tomcat-10

Tomcat 10用の実行ユーザーを作成する。

$ sudo useradd -m -U -d /opt/tomcat-10 -s /bin/false tomcat10

ファイルのオーナーを先ほど作成したユーザーに変更する。

$ sudo chown -R tomcat10: /opt/apache-tomcat-10.1.15

シェルを実行可能にする。

$ sudo sh -c 'chmod +x /opt/tomcat-10/bin/*.sh'

SystemD用のファイルを作成する。

$ sudo vi /usr/lib/systemd/system/tomcat10.service
#
# Systemd unit file for Apache Tomcat
#
[Unit]
Description=Apache Tomcat 10 Web Application Server
After=network.target
[Service]
# Configuration
Environment="JAVA_HOME=/opt/jdk-21"
Environment="JAVA_OPTS=-Djava.awt.headless=true"
Environment="CATALINA_BASE=/opt/tomcat-10"
Environment="CATALINA_HOME=/opt/tomcat-10"
Environment="CATALINA_OPTS=-Xms128m -Xmx1024m -server"
Environment="CATALINA_PID=/opt/tomcat-10/temp/tomcat.pid"
# Lifecycle
Type=forking
ExecStart=/opt/tomcat-10/bin/startup.sh
ExecStop=/opt/tomcat-10/bin/shutdown.sh
Restart=always
PIDFile=/opt/tomcat-10/temp/tomcat.pid
# Logging
SyslogIdentifier=tomcat10
# Security
User=tomcat10
Group=tomcat10
[Install]
WantedBy=multi-user.target

SystemDの設定ファイルを再読み込みする。

$ sudo systemctl daemon-reload

Tomcat 10を有効にし、起動する。

$ sudo systemctl enable --now tomcat10
Created symlink /etc/systemd/system/multi-user.target.wants/tomcat10.service  /lib/systemd/system/tomcat10.service.

正常起動を確認する。

$ sudo systemctl status tomcat10
 tomcat10.service - Apache Tomcat 10 Web Application Server
     Loaded: loaded (/lib/systemd/system/tomcat10.service; enabled; vendor pres>
     Active: active (running) since Wed 2023-10-25 05:58:29 UTC; 6s ago
    Process: 12815 ExecStart=/opt/tomcat-10/bin/startup.sh (code=exited, status>
   Main PID: 12822 (java)
      Tasks: 35 (limit: 18910)
     Memory: 101.2M
        CPU: 6.485s
     CGroup: /system.slice/tomcat10.service
             mq12822 /opt/jdk-21/bin/java -Djava.util.logging.config.file=/opt/>
10月 25 05:58:29 hostname systemd[1]: Starting Apache Tomcat 10 Web Applicati>
10月 25 05:58:29 hostname tomcat10[12815]: Tomcat started.
10月 25 05:58:29 hostname systemd[1]: Started Apache Tomcat 10 Web Applicatio>

Ubuntu Server 22.04 LTSをインストールする

目的

開発用のサーバーをUbuntu Server 22.04で再構築する。

Ubuntu Serverのインストール

下記からISOファイルをダウンロードして、USBフラッシュドライブに書き込む。
https://jp.ubuntu.com/download

SSHのインストールのチェックを入れるのを忘れずに、他はインストーラーの指示通りに入力する。

MariaDBのインストール

ここではインストールのみ行い、設定は後程行う。

sudo apt install mariadb-server
sudo mysql_secure_installation

Apache、phpのインストール

phpを使用することを前提としたインストールと、設定を行う。

sudo apt install apache2
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2ensite default-ssl
sudo apt install php libapache2-mod-php php-fpm php-common php-mbstring php-xmlrpc php-gd php-xml php-mysql php-cli php-zip php-curl php-imagick php-intl

.htaccesによる、設定の上書きを有効にする。

sudo vi /etc/apache2/apache2.conf

<Directory /var/www/>
	Options Indexes FollowSymLinks
	AllowOverride all
	Require all granted
</Directory>

sudo service apache2 restart

Webminのインストール

sudo apt install wget apt-transport-https software-properties-common

wget https://download.webmin.com/jcameron-key.asc
cat jcameron-key.asc | gpg --dearmor >jcameron-key.gpg
sudo cp jcameron-key.gpg /etc/apt/trusted.gpg.d/jcameron-key.gpg

sudo apt update
sudo apt install webmin
sudo /usr/share/webmin/changepass.pl /etc/webmin ユーザー名 パスワード

日本語設定

sudo apt install language-pack-ja
localectl list-locales | grep ja
sudo localectl set-locale LANG=ja_JP.UTF-8

Tomcat 9のインストール

sudo apt install tomcat9 tomcat9-admin

Jenkins運用のため、/etc/tomcat9/context.xmlに下記を追記する。

    <Resources cacheMaxSize="102400" />

/etc/tomcat9/server.xmlのAJP/1.3の設定を下記の通り変更する。

    <Connector protocol="AJP/1.3"
               address="localhost"
               port="8009"
               redirectPort="8443"
               secretRequired="false" />

/etc/tomcat9/tomcat-users.xmlに下記を追記する。

  <role rolename="manager-script"/>
  <user username="ユーザー名" password="パスワード" roles="manager-script"/>

/usr/lib/systemd/system/tomcat9.serviceに下記を追記する。

Environment="CATALINA_OPTS=-DJENKINS_HOME=/opt/jenkins/"
ReadWritePaths=/opt/jenkins/

/etc/tomcat9/policy.d/50local.policyに下記を追記する。

grant codeBase "file:${catalina.base}/webapps/jenkins/-" {
    permission java.security.AllPermission;
};
grant codeBase "file:/opt/jenkins/-" {
    permission java.security.AllPermission;
};
sudo systemctl daemon-reload
sudo service tomcat9 restart

Jenkinsのインストール

/opt/jenkinsフォルダを作成し、フォルダにTomcatから書き込み可能な権限を付与する。

jenkins.warファイルをダウンロードし、/var/lib/tomcat9/webapps/に配置する。

ApacheとTomcatの連携の設定

sudo a2enmod proxy
sudo a2enmod proxy_ajp

/etc/apache2/conf-enabled/tomcat.confを作成し、下記の通り記載する。

ProxyPass /jenkins/ ajp://localhost:8009/jenkins/
ProxyPassReverse /jenkins/ ajp://localhost:8009/jenkins/
sudo service apache2 restart

Postfixのインストール

こちらのページにインストールと設定方法を記載した。

Apache Tomcat 9.0.31にアップデートしたらエラー発生

Apache Tomcat 9.0.31にアップデートしたらAJP経由でアクセス出来なくなった。
server.xmlを見てみるとAJPの設定がコメントアウトされていたので、下記を追記した。

    <Connector protocol="AJP/1.3"
               port="8009"
               redirectPort="8443"/>

しかし、今度は下記のようなエラーが出るようになった。

Caused by: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.
    at org.apache.coyote.ajp.AbstractAjpProtocol.start(AbstractAjpProtocol.java:264)
    at org.apache.catalina.connector.Connector.startInternal(Connector.java:1035)

secretRequiredがデフォルトで”true”になっているため、secretを設定しろということらしい。
面倒なのでアドレスでアクセス制限をかけて、secretRequiredは”false”にした。

<Connector protocol="AJP/1.3"
           address="localhost"
           port="8009"
           redirectPort="8443"
           secretRequired="false"/>