🧩

【Mac】外部TomcatにSpring Bootアプリをデプロイしたが、サーバがうまく起動しなかったことから得た学び

2024/08/05に公開

はじめに

ローカル環境内の外部Tomcatにアプリをデプロイした際に、サーバの起動がうまくいかなかったため今回学んだ知識や解決内容も含め備忘録として残します。

対象者

・現在、業務中にJavaを使用されていて経験年数が1〜3年目くらいの方
・外部のTomcatにアプリをデプロイすることに興味がある方、したことがない方
・Tomcatについて、あまり良くわかっていないという方

環境

・JDK:21
・Spring Boot:3.3.2
・Tomcat:10.1.25

前提

  1. SpringBootアプリをMavenでビルドし、warファイルを出力
  2. 1で出力したwarファイルを、Tomcatのwebappsディレクトリに配置
  3. 「java -version」で表示されるバージョンとアプリのバージョンが一致している

そもそもTomcatとは?

正式名称が「Apache Tomcat」という所謂Webアプリケーションサーバ。
(「Apache」というと、「Apache HTTP Server」の事を指すから混乱しないように気をつけたい。)
Webコンテナを内包しているので、単独でWebサーバとして動作することも可能だが、Webサーバの部分はApacheやNginxに任せるのが一般的。Tomcatについて深ぼると長くなってしまうので、詳しくは下記のような記事を参考にしていただきたい。
https://contextpath.zealseeds.com/basicKnowledge/Tomcat/index.html

本題(原因)

今回うまくいかなかった原因は、結論必要なポートが既に使われていたから。(そんだけかい!!)
はい、そんだけです笑 ただ、対象ポートが8005だったためそもそも自分の知識の範囲外だったこともあり苦戦しました。(8080だけ確保しておけば良いという、安直な考えでした。)
まず、今回Tomcatのサーバを動かしてみて発見したのは、起動時に使われるポートが複数種類あるということです。
下記に具体的なポートと使用用途について記載します。

◾️Tomcat起動時に使用されるポート
(今回使用されていてエラーとなっていたのは、8005でした。)
・8080: HTTPリクエスト用
・8005: シャットダウン用
・8009: AJPリクエスト用
・8443: HTTPSリクエスト用

Tomcatの起動方法

シェルの実行ファイルの階層まで移動。

cd /Applications/Eclipse_2024-06.app/Contents/tomcat/10/bin

Tomcatサーバを起動。

./startup.sh

すると...

Using CATALINA_BASE:   /Applications/Eclipse_2024-06.app/Contents/tomcat/10
Using CATALINA_HOME:   /Applications/Eclipse_2024-06.app/Contents/tomcat/10
Using CATALINA_TMPDIR: /Applications/Eclipse_2024-06.app/Contents/tomcat/10/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
Using CLASSPATH:       /Applications/Eclipse_2024-06.app/Contents/tomcat/10/bin/bootstrap.jar:/Applications/Eclipse_2024-06.app/Contents/tomcat/10/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.

これだけ見ると上手くいってるようにも見える、、、
ここで大事なのがログの確認。

ログの確認方法

コマンドの例としては下記になります。(エディタやTomcatのバージョンによって適宜変更が必要)

cat /Applications/Eclipse_2024-06.app/Contents/tomcat/10/logs/catalina.out

今回エラーが出ていた箇所

04-Aug-2024 19:55:25.204 重大 [main] org.apache.catalina.core.StandardServer.await アドレス [localhost] のポート番号 [8005] にサーバー停止ソケットを作成できませんでした (基本ポート番号は [8005]、オフセットは [0] です)
	java.net.BindException: Address already in use
		at java.base/sun.nio.ch.Net.bind0(Native Method)
		at java.base/sun.nio.ch.Net.bind(Net.java:565)
		at java.base/sun.nio.ch.Net.bind(Net.java:554)
  1. ポートの確認方法
lsof -i :8005

使用されている場合、下記のように表示されます。(使用されていない場合は、何も表示されません)

COMMAND   PID      USER     FD   TYPE    DEVICE SIZE/OFF NODE NAME
java      86977    username  48u  IPv6    0x19638c9a81fedb9b  0t0  TCP localhost:8005 (LISTEN)
  1. 対象ポートのプロセスを終了する方法
kill -9 <PID>

※<PID>は、1で表示された内容でいうと、「86977」を指します。
ちなみに、PIDとは「Process ID」の略です。

最後に

今回は、ミドルウェアについての弱さが目立った躓きでした。アプリの開発とは別にインフラ周りも含めて概念だけでなく、具体的な内容を少しずつでも落とし込まないといけないなと日々感じます。そのためにも自分の中の「知らない」と向き合って、空いた時間を使ってこういった小さな積み重ねで補っていければと思います。もし、表現や内容に誤りなどあればご指摘いただければ幸いです。最後まで読んでいただきありがとうございました!

補足

・Tomcatサーバの停止方法

./shutdown.sh

・コマンド実行時に「zsh: permission denied: ./shutdown.sh」などの内容が返ってきた場合
下記コマンドで権限を付与。

chmod +x shutdown.sh

Discussion