「Tomcatって結局なに?」「Apacheとは何が違うの?」「サーブレットやJSPとはどういう関係?」。JavaでWeb開発に関わると、こうした言葉がまとめて押し寄せてきます。
この記事では、Tomcat・サーブレット・JSP・Apacheの4つを、役割と関係から順番に整理します。
後半では、現場の定番である「Apache+Tomcat」の連携構成を、mod_proxyの設定例やTomcat側・Spring Boot側の設定まで含めて解説します。
頭から順に読めば全体像がつながり、実務で設定を任されたときにも、どのファイルの何を触ればいいか迷わなくなります。
この記事でわかること
- Tomcatの正体(サーブレットコンテナ)と、中身の部品・フォルダ構成
- サーブレットとJSPの役割と、Tomcatとの関係
- ApacheとTomcatの違いと、連携させる理由・仕組み
- mod_proxy・AJPの設定例と、HTTPS化・負荷分散・Spring Bootでの設定
- よくあるトラブル(404/502エラー)の原因と対処法
PARTS LIST /目次
- Tomcatとは?基礎を一気におさらい
- サーブレットとJSPとは?Tomcatとの関係
- Apacheとは?Tomcatとの違いと役割分担
- Tomcatの使い方:起動からフォルダ構成・設定ファイルまで
- なぜ現場では「Tomcat+Apache構成」が選ばれるのか
- TomcatとApache連携の基本的な仕組みをイメージで理解する
- TomcatとApacheの連携方式を全体像で理解する
- どの連携方式を選ぶべきかの判断基準
- 連携構成でよく起きるトラブルとその原因
- Apache×Tomcat連携で押さえておくべき注意点
- よくある質問
- Q1. TomcatとApacheを連携させる理由は何ですか?
- Q2. mod_proxyとAJP、どちらを選ぶべきですか?
- Q3. 502 Bad Gatewayが出る原因は何ですか?
- Q4. Apacheのモジュールを有効化するにはどうすればいいですか?
- Q5. TomcatのポートをApache経由に統一するセキュリティ上のメリットは?
- Q6. Tomcatとは何ですか?
- Q7. Tomcatは無料で使えますか?
- Q8. Tomcat単体でもWebサーバーとして動きますか?
- Q9. Tomcatの「Catalina」とは何ですか?
- Q10. Spring BootでもTomcatの知識は必要ですか?
- Q11. サーブレットとJSPの違いは何ですか?
- Q12. JSPは今でも使われていますか?
- この記事を読んだあとに取るべき次の一手
Tomcatとは?基礎を一気におさらい
まずは主役のTomcatから整理します。Tomcatが何者で、中で何が動いているのかがわかると、このあと出てくるサーブレット・JSP・Apacheとの関係がすっと頭に入ります。
Tomcatの正体(サーブレットコンテナ)
Tomcatとは、JavaサーブレットやJSPを実行するためのオープンソースソフトウェアで、正式名称は「Apache Tomcat」です。
カテゴリとしては「サーブレットコンテナ」や「アプリケーションサーバー」と呼ばれます。開発しているのはApache Software Foundationという非営利団体で、誰でも無料で使えます。
一言でまとめると「Javaで書いたWebアプリを、実際にブラウザから使える状態にしてくれる土台」です。リクエストを受け取り、プログラムを実行し、結果をブラウザに返す。その一連の流れを引き受けてくれるのがTomcatです。
2026年9月時点で公式にサポートされているのは、11.0・10.1・9.0の3系列です。
2026年9月時点(公式サイト「Which Version」より)
これから学ぶならTomcat 11.0を選べば問題ありません。注意したいのは、10以降でサーブレットのパッケージ名がjavax.*からjakarta.*に変わった点です。古い参考書のコードを11.0で動かすと、コンパイルエラーになります。既存システムが9.0で動いている現場もまだ多いため、配属先のバージョンは最初に確認しておきましょう。
サーブレットコンテナとしてTomcatが担う3つの仕事
「サーブレットコンテナ」という呼び名は、Tomcatがサーブレットを動かす"容れ物"であることを示しています。具体的には、Tomcatの仕事は大きく分けて次の3つです。
- リクエストの受付:ブラウザからのHTTPリクエストを受け取る
- サーブレットの実行:リクエストに対応するJavaプログラムを呼び出して処理する
- レスポンスの返却:処理結果をHTMLなどの形でブラウザに返す
この3つを引き受けるために、サーブレットコンテナは裏側でサーブレットのライフサイクル管理も行っています。具体的には、サーブレットのインスタンスを必要なタイミングで生成し、リクエストが来るたびに使い回し、アプリ終了時に破棄する、という一連の管理です。
開発者は、この生成・破棄のタイミング管理を自分で書く必要がありません。「リクエストが来たら何をするか」というサーブレットの処理内容だけを書けば、インスタンス管理やスレッドの割り当てはTomcatが自動でやってくれます。
この分業のおかげで、開発者はインフラ的な面倒ごとから離れて、ビジネスロジックに集中できるわけです。
Tomcatの中身:Catalina・Coyote・Jasperの3つの部品
Tomcatは1つのソフトに見えますが、中は役割の違う部品の組み合わせです。名前だけでも知っておくと、ログやエラーメッセージを読むときに迷いません。
- Coyote(コヨーテ):HTTPやAJPのリクエストを受け付ける「コネクタ」。server.xmlの
<Connector>がこれにあたる - Catalina(カタリナ):サーブレットを実行するサーブレットコンテナ本体。Tomcatの中核
- Jasper(ジャスパー):JSPをサーブレットに変換してコンパイルする「JSPエンジン」
リクエストは「Coyoteが受け付ける → Catalinaがサーブレットを動かす(JSPならJasperが事前に変換しておく)」の順に流れます。
この構造は、Tomcat本体の設定ファイルserver.xmlの入れ子にもそのまま表れています。Serverの中にServiceがあり、その中に受付役のConnectorと処理役のEngine、さらにその下にホスト(Host)とアプリ(Context)が並ぶ形です。後半の連携設定でConnectorやHostが出てきたら、この入れ子を思い出してください。
名前の由来
Tomcat:作者のJames Duncan Davidsonが命名。オープンソースのプロジェクトにはオライリー社の解説書(表紙に動物が描かれるシリーズ)が出ることが多かったため動物名にしようと考え、「小さくても自分の身は自分で守れる」雄猫(tomcat)を選んだそうです(Apache Tomcat公式Wiki)。
Catalina:中核部分のコードを書いたCraig McClanahanによると、ロサンゼルス沖のカタリナ島が好きだったことから付けた名前です。島にはAvalonという町があり、当時内部の設計にAvalon Frameworkを使う案があったことにも掛けているといいます。
Jasper:JSPの文字(JaSPer)に掛けた名前だと言われています。
Tomcatと他のアプリケーションサーバーの違い
Javaのアプリケーションサーバーには、Tomcat以外にもいくつか選択肢があります。大きな違いは、Java EE(現Jakarta EE)の仕様をどこまで実装しているかです。
Tomcatが実装しているのは、サーブレットやJSPなどWebアプリに必要な一部の仕様だけです。WildFlyなどのフル機能のAPサーバーにはあって、Tomcatにない代表例が次の2つです。
- EJB(Enterprise JavaBeans、現Jakarta Enterprise Beans):業務処理を書くための部品(コンポーネント)の仕様。トランザクション管理・権限チェック・別サーバーからの呼び出しなどを、APサーバー側が自動で引き受けてくれる。2000年代の企業システムで広く使われた
- JMS(Java Message Service、現Jakarta Messaging):アプリ同士がキュー経由でメッセージをやり取りするための仕様。「注文を受け付けたら、在庫処理は後で非同期に行う」といった連携に使う
どちらも強力ですが、そのぶんAPサーバーが大きく重くなります。今はEJBの代わりにSpringの@Transactionalなどでトランザクションを管理し、メッセージングもKafkaやRabbitMQなどを必要なときにライブラリで足すのが一般的です。
Tomcatはこうした重量級の仕様を持たないぶん、軽くて扱いやすく、Spring Bootのように必要な機能をライブラリで足していく今どきの開発スタイルとも相性が良いため、事実上の定番になっています。
サーブレットとJSPとは?Tomcatとの関係
Tomcatが「動かすもの」の正体が、サーブレットとJSPです。ここでは2つの役割と、Tomcatの中でどう扱われているかを見ていきます。
サーブレットとJSPとは何か?
サーブレットとは、Webサーバー上で動くJavaプログラムです。ブラウザからのリクエストを受け取り、処理結果をHTMLとして返します。
JSP(JavaServer Pages)は、HTMLの中にJavaのコードを埋め込める仕組みで、画面表示を作るのに使われてきました。
ざっくり言えば、サーブレットは「処理担当」、JSPは「見た目担当」。そして両方とも、単体では動けません。動かすための実行環境、つまりTomcatが必要になります。
JSPが最初の1回だけ遅い理由とプリコンパイル
JSPはそのままの形で実行されるわけではありません。初めてアクセスされたときに、TomcatがJSPをJavaのコード(サーブレット)に変換し、さらにクラスファイルへコンパイルしてから実行します。生成物はTomcatのworkフォルダに置かれます。
そのため、JSPは最初の1回だけ表示が遅くなります。本番でこれを避けたい場合は、ビルド時にまとめてコンパイルしておく「プリコンパイル」を使います。TomcatにはJSPを事前変換するJspC(Antタスク)が付属しており、Mavenならjspcプラグインで同じことができます。
ちなみに「JSPを直したのに画面が変わらない」ときは、workフォルダ内のそのアプリの生成物を消してTomcatを再起動すると、作り直されて反映されることがあります。現場でよく使う切り分けの一手です。
JSPは古い?サーブレットとJSPの今の位置づけ
「サーブレットやJSPはもう古い」という声を聞くことがあります。半分は正解で、半分は誤解です。
JSPは、新規開発ではあまり選ばれなくなりました。HTMLとJavaのコードが1つのファイルに混ざって保守しにくいうえ、Spring Bootの実行可能JARでは使えないためです。今の主流は、Thymeleafなどのテンプレートエンジンを使うか、画面をReactなどのフロントエンドに任せてJava側はAPIだけを返す構成です。
一方で、サーブレットの仕組みそのものは今も現役です。Spring MVCは内部でDispatcherServletというサーブレットを1つ動かし、そこからすべてのリクエストを各コントローラーに振り分けています。普段サーブレットを直接書かなくても、土台ではサーブレットとTomcatが動いているわけです。
JSPやサーブレットで作られた既存システムもまだ多く残っています。保守の現場では今でも読めることが求められるので、基本は押さえておいて損はありません。
Apacheとは?Tomcatとの違いと役割分担
ここまででTomcatとサーブレット・JSPの関係が見えてきました。次は、Tomcatと名前が似ていて混同されやすいApacheを整理します。
Apache(Apache HTTP Server)とは
この記事で「Apache」と呼んでいるのは、Apache HTTP ServerというWebサーバーソフトのことです。無料で使えるオープンソースで、ブラウザからのリクエストを受けてファイルを返す、Webの玄関口の役割を担います。
RHEL・Rocky Linux系ではパッケージ名もサービス名もhttpd、Ubuntu・Debian系ではapache2です。この記事の後半に出てくるhttpdも、同じApacheを指しています。
紛らわしいのが、「Apache」は開発元の団体Apache Software Foundationの名前でもある点です。実はTomcatも同じ団体のプロジェクトで、正式名称は「Apache Tomcat」。名前は似ていますが、ApacheとTomcatは別のソフトです。
また、Apacheはモジュールを足して機能を増やす作りになっています。後半で使うmod_proxyやmod_proxy_ajpも、Tomcatへリクエストを中継するためのモジュールです。
そもそもTomcatとApacheは役割が違う
Apacheは「Webサーバー」として、画像やHTMLなどの静的なファイルを配るのが大の得意です。
一方でTomcatは「アプリケーションサーバー」であり、Javaを動かして計算やデータベース処理を行うためのもの。
例えるなら、Apacheはテキパキと注文をさばく「ホールスタッフ」で、Tomcatは奥で料理を作る「シェフ」のような関係です。
役割を分けることで、それぞれの作業に集中できる環境が整います。
Apache・Tomcat・サーブレット・JSPの関係を1枚にまとめると、次のようになります。
ApacheとNginxの違い
Tomcatの前に置くWebサーバーとしては、ApacheのほかにNginx(エンジンエックス)もよく使われます。
- Apache:歴史が長く、モジュールが豊富。ディレクトリごとに
.htaccessで設定を変えられるなど、柔軟な設定が得意 - Nginx:少ないメモリで大量の同時接続をさばくのが得意。設定がシンプルで、リバースプロキシ用途で人気が高い
どちらを前に置いても、「静的ファイルはWebサーバー、Javaの処理はTomcat」という役割分担は同じです。ただしNginxは標準ではAJPに対応していないため、Tomcatとの連携はHTTP(proxy_pass)で行います。この記事ではApacheとの連携を解説するので、Nginxで組みたい方は次の記事を参考にしてください。
Tomcatの使い方:起動からフォルダ構成・設定ファイルまで
役割がわかったところで、実際にTomcatを動かしてみましょう。起動の手順に加えて、現場で必ず触ることになるフォルダ構成と設定ファイルも押さえておきます。
Tomcatの使い方:起動までの3ステップ
Tomcatは「Javaを入れる → Tomcatを入れて起動する → ブラウザで確認する」の3ステップで動かせます。難しい設定は不要で、初回でも15分あれば終わります。
まずJava(JDK)が入っているかを確認します。
java -version
バージョンが表示されればOKです。Tomcat 11.0を使うならJava 17以上、10.1ならJava 11以上が必要です。入っていなければEclipse TemurinなどのJDKをインストールしましょう。
次に公式サイトからzipやtar.gzをダウンロードして、好きな場所に解凍します。インストーラーは不要で、解凍した中のbinフォルダにあるスクリプトを実行するだけです。
# Mac / Linuxの場合
cd apache-tomcat-11.0.x/bin
./startup.sh
# Windowsの場合は startup.bat をダブルクリック
止めたいときは同じフォルダのshutdown.shを実行します。ローカルのJava環境を汚したくない場合は、Dockerで公式イメージを起動する方法もあります。
起動したらブラウザでhttp://localhost:8080を開いてください。猫のロゴ入りのデフォルトページが表示されれば成功です。Tomcatは標準でポート8080を使うので、現場で「8080見といて」と言われたら、たいていTomcatの話だと思って間違いありません。
Tomcatのフォルダ構成とログの見方
ダウンロードしたTomcatを解凍すると、次のようなフォルダが並んでいます。
apache-tomcat-11.0.x/
├── bin/ … 起動・停止スクリプト(startup.sh、shutdown.sh、catalina.sh など)
├── conf/ … 設定ファイル(server.xml、web.xml、context.xml、tomcat-users.xml など)
├── lib/ … Tomcat本体と、全アプリで共有するJAR
├── logs/ … ログファイル
├── webapps/ … アプリの置き場所(WARファイルをここに置くとデプロイされる)
├── work/ … JSPを変換・コンパイルした生成物
└── temp/ … 一時ファイル
よく触るのはconf・webapps・logsの3つです。メモリ設定などの起動オプションを変えたいときは、binにsetenv.sh(Windowsはsetenv.bat)を自分で作って書くのが作法です。catalina.shを直接書き換えると、バージョンアップのときに設定が消えてしまいます。
# bin/setenv.sh(自分で新規作成する。起動時に自動で読み込まれる)
CATALINA_OPTS="-Xms512m -Xmx1024m"
-Xmsは起動時、-Xmxは最大のヒープメモリです(値は例なので、サーバーのメモリに合わせて調整してください)。JAVA_OPTSに書く方法もありますが、こちらは停止コマンドの実行時にも適用されるため、Tomcat本体だけに効かせたい設定はCATALINA_OPTSに書くのが一般的です。
同時に処理できるリクエスト数の上限は、server.xmlのHTTPコネクタのmaxThreadsで決まります。初期値は200です。足りないとリクエストが待たされますが、むやみに増やすとメモリを圧迫するので、ヒープの設定とセットで考えます。
トラブルのときに開くのはlogsフォルダです。主なログは次のとおりです。
catalina.out:Linux・macOSでcatalina.sh経由で起動したときの標準出力。起動エラーやアプリのSystem.outの出力はまずここを見るcatalina.日付.log:Tomcat本体の起動・停止やエラーの記録localhost.日付.log:アプリ(ホスト単位)で起きたエラーの記録。アプリが起動しないときに原因が出ていることが多いlocalhost_access_log.日付.txt:どのURLに、いつ、どんなステータスで応答したかのアクセスログ
なお、webappsの中にあるmanagerとhost-managerは、ブラウザからアプリのデプロイや仮想ホストの管理ができる管理画面です。conf/tomcat-users.xmlにユーザーを登録すると使えるようになりますが、本番環境では外部からアクセスできないようにしておきましょう。
本番ではサービスとして常駐させる
startup.shでの手動起動は、開発や動作確認向けです。本番のLinuxサーバーでは、systemdのサービスとして登録し、サーバー起動時に自動で立ち上がるようにします。Tomcat専用の一般ユーザーで動かすのも基本です(rootで動かすと、万一乗っ取られたときの被害が大きくなります)。
# /etc/systemd/system/tomcat.service
[Unit]
Description=Apache Tomcat
After=network.target
[Service]
Type=simple
User=tomcat
Group=tomcat
Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk
Environment=CATALINA_HOME=/opt/tomcat
ExecStart=/opt/tomcat/bin/catalina.sh run
Restart=on-failure
[Install]
WantedBy=multi-user.target
ファイルを置いたらsudo systemctl daemon-reloadで読み込み、sudo systemctl enable --now tomcatで自動起動の登録と起動を同時に行います。パスは環境に合わせて変えてください。
この書き方ではcatalina.sh runでTomcatを前面で動かし、停止はsystemdに任せます。そのため標準出力はcatalina.outではなく、journalctl -u tomcatで確認します。Windowsの場合は、公式サイトの「Windows Service Installer」版でインストールすると、Windowsのサービスとして登録されます。
WARファイル・設定ファイル・Spring Bootとの関係
起動できたら、次は現場の会話に出てくる頻出ワードを押さえましょう。
WARファイルとは、Webアプリ一式(クラスファイル・JSP・設定など)を1つに固めたアーカイブです。TomcatのwebappsフォルダにWARファイルを置くと、自動で展開されてアプリが公開されます。この作業を「デプロイ」と呼びます。
WARファイルの中身は、決まったフォルダ構成になっています。ポイントはWEB-INFフォルダです。
myapp.war
├── index.html ← ブラウザから直接開ける
├── css/style.css ← ブラウザから直接開ける
└── WEB-INF/ ← ここから下は直接開けない
├── web.xml … アプリの設定
├── classes/ … コンパイル済みのクラス(サーブレットなど)
├── lib/ … 依存ライブラリのJAR
└── views/hello.jsp … サーブレット経由でだけ表示するJSP
WEB-INFの下にあるファイルは、ブラウザからURLを指定しても直接開けません(Tomcatが404を返します)。設定ファイルやクラスファイルが外から覗かれないのはこの仕組みのおかげです。
これを利用して、JSPをWEB-INFの下に置くのが定番の作り方です。こうするとJSPはサーブレットから転送されたときにしか表示されず、「処理を飛ばして画面だけ直接開かれる」ことを防げます。逆に、画像やCSSなどブラウザに配るファイルはWEB-INFの外に置きます。
設定ファイルで頻出なのがserver.xmlとweb.xmlの2つです。置き場所と役割は次のとおりです。
conf/server.xml(Tomcatのインストール先の中):Tomcat本体の設定。待ち受けポート(Connector)、ログ(Valve)、ホストなどを定義するWEB-INF/web.xml(各Webアプリの中):そのアプリだけの設定。URLとサーブレットの対応付け、セッションの有効期限、エラーページなどを定義するconf/web.xml:全アプリ共通の初期設定。静的ファイルやJSPを処理する仕組みもここで定義されていて、普段は触らない
web.xmlでサーブレットを登録する最小例は次のとおりです。/helloへのアクセスをHelloServletクラスに渡します。
<!-- WEB-INF/web.xml(versionはTomcat 11.0なら6.1、10.1なら6.0) -->
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" version="6.1">
<!-- サーブレットに名前を付けて登録する -->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.example.HelloServlet</servlet-class>
</servlet>
<!-- URLとサーブレットを対応付ける -->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
もっとも今は、クラスに@WebServlet("/hello")アノテーションを付ければ同じ登録ができるため、web.xmlを持たないアプリも珍しくありません。また、後述するSpring Bootではserver.xmlもweb.xmlも使わず、ポートなどはapplication.propertiesで設定します。
「本体の設定はserver.xml、アプリの設定はweb.xml」と覚えておけば、設定変更を頼まれたときにどのファイルを開けばいいか迷いません。
最近のJava開発の主流であるSpring Bootには、実はTomcatが最初から内蔵されています。java -jarでアプリを起動すると、中で組み込み版Tomcatが動く仕組みです。「Spring Bootの現場だからTomcatの知識は不要」ではなく、むしろ逆。中で動いているのはTomcatなので、ポートやスレッドの設定・エラーの切り分けには、ここまでの知識がそのまま活きます。
Tomcatの内部構造をさらに体系的に理解したい方には以下の書籍もおすすめです。
なぜ現場では「Tomcat+Apache構成」が選ばれるのか
IT業界には「枯れた技術」という言葉がありますが、この構成こそがそれです。
新しい技術が次々と出てくる中で、なぜ未だにこの組み合わせが王道なのか、その本質に迫ります。
連携すると解決できる具体的な課題
ApacheとTomcatを連携させて一番大きく変わるのは、表示速度と安定感です。画像やCSSの読み込みをApacheに任せると、Tomcatの負担が減りJavaの処理が高速化します。
また、Apache側で「メンテナンス中」の画面を出すのも簡単になるため、運用の自由度が上がります。
Tomcatを再起動している間、ユーザーに真っ白な画面を見せなくて済むのは、精神衛生的にも良い選択です。
Tomcat単体運用では困りやすいポイント
TomcatだけでもWebサイトは公開できますが、アクセスが増えたときの余裕が小さくなりがちです。
画像やCSSの配信までTomcatに任せると、本来Javaの処理に使いたいスレッドを静的ファイルのために消費してしまうからです。
さらに、セキュリティ設定の細かさでもApacheに軍配が上がります。
特定のIPアドレスを遮断したり、複雑なURLのリライトをしたりといった作業をTomcatでやるのは、正直言って苦行でしかありません。
静的コンテンツと動的処理を分ける意味
Webページには、毎回内容が変わる「動的な部分」と、いつ見ても同じ「画像やスクリプト」があります。
これらを混ぜてTomcatに処理させるのは、非効率の極み。
Apacheに静的なものを任せることで、Tomcatは重たい計算だけに専念できます。この「分業」こそが、システムの寿命を延ばす鍵。
私も昔、全部Tomcatに投げた結果、画像の読み込みだけでサーバーが悲鳴を上げた苦い経験があります。
リバースプロキシとしてApacheを置く設計思想
Apacheを「窓口(リバースプロキシ)」に据えることで、Tomcatの存在を隠せるのが大きなメリット。
外部からのアクセスをApacheが一度受け止め、中身を確認してから安全にTomcatへ流します。
これによって、外部にTomcatのポート(8080など)を晒す必要がなくなります。守備を固めるための「城壁」を一枚挟むイメージ。
万が一Apacheが攻撃されても、心臓部のTomcatまで到達する時間を稼げます。
企業システムでこの構成が多い理由
企業が求めるのは「明日も同じように動くこと」です。
ApacheとTomcatの連携は20年以上の実績があり、トラブル時のノウハウがネット上に溢れています。
私らエンジニアにとっても、何かあったときに「ググればすぐ解決策が見つかる」というのは最強の安心材料。
奇をてらった最新構成よりも、信頼できる定番を選ぶのがプロの仕事だと私は考えています。
TomcatとApache連携の基本的な仕組みをイメージで理解する
理屈だけだと眠くなるので、パケットがどう流れるかを「バケツリレー」に例えて説明します。
リクエストが流れる順番を噛み砕いて説明
- ユーザーがブラウザでポチる(HTTPリクエスト)。
- Apache(門番)がそれを受け取る。
- Apacheが「あ、これはJavaが必要なやつだ」と判断する。
- Tomcat(職人)に「これ頼むわ」と投げる。この4ステップ。門番がいかに正確に、素早く職人に渡せるかが勝負です。
ApacheからTomcatへ処理が渡る瞬間
ここでmod_proxyなどが活躍します。
Apacheは自分では中身を作らず、Tomcatに対して「裏側でもう一度リクエストを投げる」ような動きをします。
このとき、ApacheはユーザーのIPアドレスなどの情報を、特別な「ヘッダー」に詰め込んで渡してくれます。
これを忘れると、Tomcat側で「全部localhostからのアクセスだ」と勘違いして、ログが使い物にならなくなるので気をつけましょう。
レスポンスが返るまでに何が起きているか
Tomcatが処理を終えると、結果をApacheに返します。Apacheはそれを受け取り、必要ならヘッダーを書き換えてユーザーに届けます。
この帰り道で、Apacheがデータを圧縮(gzipなど)して送ることで、通信量を節約することも可能です。
職人が作った料理に、ホールスタッフがラップをかけて運んでくれるような気遣いですね。
TomcatとApacheの連携方式を全体像で理解する
連携と言っても、そのやり方はいくつかあります。現在の主流と、かつての定番を比較しながら全体マップを見ていきましょう。
代表的な連携方式の全体マップ
大きく分けて、mod_proxyを使う方法と、AJPという専用プロトコルを使う方法の2種類。
以前は「AJPこそが正義」という風潮もありましたが、今はHTTPでやり取りするmod_proxyが主流です。
下手に凝ったことをするよりも、シンプルにHTTPで繋ぐ方が、トラブルシューティングもしやすくなります。
2つの方式で、Apache側のモジュールとTomcat側の受け口(コネクタ)がどう対応するかを図にすると次のとおりです。
mod_proxy_httpmod_proxy_ajp / mod_jkmod_proxyを使ったシンプルな連携
これはApacheが受け取ったリクエストを、そのままTomcatに横流しする方式です。
まず、Apacheでmod_proxyとmod_proxy_httpモジュールを有効化する必要があります。
Ubuntu/Debian系なら以下のコマンドで有効化できます。
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo systemctl restart apache2
設定はシンプルで、数行の記述で動きます。
ProxyPass /app/ http://localhost:8080/app/
ProxyPassReverse /app/ http://localhost:8080/app/
HTTPという標準的なルールを使うため、専用の仕組みを覚える必要がありません。私も最近の案件では、迷わずこの方式を選んでいます。
VirtualHostにまとめた実運用向けの設定例
上の2行は動作確認用の最小構成です。実際に運用するときは、VirtualHostの中に次のような形でまとめておくと管理しやすくなります。
<VirtualHost *:80>
ServerName example.com
# 画像・CSSなどの静的ファイルはApacheが直接返す
DocumentRoot /var/www/html
ProxyPass /app/static/ !
# 動的ページだけTomcat(HTTPコネクタ:8080)へ転送
ProxyPreserveHost On
ProxyPass /app/ http://127.0.0.1:8080/app/ timeout=60
ProxyPassReverse /app/ http://127.0.0.1:8080/app/
</VirtualHost>
ProxyPreserveHost Onは、ブラウザが指定したホスト名をそのままTomcatへ渡す設定です。これが無いと、Tomcat側が生成するリダイレクト先URLが127.0.0.1:8080になってしまうことがあります。
ProxyPass /app/static/ !のように末尾に!を付けたパスは転送対象から外れ、Apacheが自分で返します。除外ルールは、より広い/app/の転送ルールより前に書くのがポイントです。
なお、RHEL・Rocky Linux系のhttpdではa2enmodコマンドがありません。/etc/httpd/conf.modules.d/00-proxy.confにproxy_moduleとproxy_http_moduleのLoadModule行が有効になっているかを確認してください。
Tomcat側の設定(server.xml)も見直す
ここまではApache側の設定でした。mod_proxyで連携するときは、Tomcat側のconf/server.xmlも2か所見直しておくと安心です。
1つ目は、HTTPコネクタの待ち受けをローカルに絞ることです。address="127.0.0.1"を付けると、8080番は同じサーバー内のApacheからしか受け付けなくなります。ファイアウォールで8080番を閉じる対策と合わせれば、二重の守りになります。
<!-- conf/server.xml:HTTPコネクタ(初期設定に address を追加) -->
<Connector port="8080" protocol="HTTP/1.1"
address="127.0.0.1"
connectionTimeout="20000"
redirectPort="8443" />
ApacheとTomcatを別々のサーバーに置く場合は、127.0.0.1ではなく、Apacheからの通信を受けるネットワーク側のIPアドレスを指定してください。
2つ目は、接続元IPの引き継ぎです。Apacheを挟むと、Tomcatから見たアクセス元はすべてApacheになり、アクセスログもアプリのrequest.getRemoteAddr()もApacheのIPになってしまいます。mod_proxyは本来の接続元をX-Forwarded-Forヘッダーで渡してくれるので、Tomcat側ではRemoteIpValveでそれを読み取ります。
<!-- conf/server.xml:<Host> の中に追加 -->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto" />
<!-- 既存のアクセスログ設定に requestAttributesEnabled を追加 -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
requestAttributesEnabled="true"
pattern="%h %l %u %t "%r" %s %b" />
RemoteIpValveがヘッダーを信用するのは、信頼できるプロキシ(初期設定ではループバックとプライベートIPアドレス)から届いたリクエストだけです。Apacheがそれ以外のIPアドレスにある場合は、internalProxies属性でApacheのIPを指定してください。
protocolHeaderは、Apacheが受けた通信がHTTPSだったかどうかをTomcatに伝えるための設定です。Apache側の準備も含めて、次の「HTTPS化」の見出しで説明します。
アクセスログに本当の接続元IPが残っていれば、後半で触れるApacheとTomcatのログの突き合わせもぐっと楽になります。
Spring Bootの場合はapplication.propertiesで設定する
Spring Bootのアプリをjava -jarで動かしている場合、中で動いているのは組み込み版のTomcatです。この組み込み版にはserver.xmlがありません。そのため、上で紹介した設定はapplication.propertiesに書きます。
# application.properties(Spring Boot)
# 待ち受けをローカルに絞る(server.xmlの address に相当)
server.address=127.0.0.1
server.port=8080
# X-Forwarded-For などのヘッダーを読む(RemoteIpValve に相当)
server.forward-headers-strategy=native
server.forward-headers-strategy=nativeを指定すると、Spring Bootが組み込みTomcatにRemoteIpValveを設定してくれます。信頼するプロキシのIPアドレスなどを細かく変えたい場合は、server.tomcat.remoteip.internal-proxiesなどのserver.tomcat.remoteip.*で調整します。Apache側のProxyPassの書き方は、転送先が組み込みTomcatのポートになるだけで、ここまでと同じです。
Spring Bootで連携するときに気をつけたい点が2つあります。
- 実行可能JARではJSPが使えない:Spring Bootの公式ドキュメントでも、JSPは実行可能JARではサポート外とされています。JSPを使うならWAR形式でパッケージする必要があります。新規開発ならThymeleafなどのテンプレートエンジンを使うのが一般的です
- 外部のTomcatにWARで載せる方法もある:
SpringBootServletInitializerを継承したクラスを用意してWARでビルドすれば、従来どおりTomcatのwebappsにデプロイできます。この場合は組み込み版ではなく外部Tomcatのserver.xmlが使われるので、設定は前の見出しの方法に戻ります
HTTPS化:SSLはApacheで受けてTomcatには平文で渡す
連携構成でHTTPSに対応するときの定番は、SSL/TLSの処理をApacheに任せる形です。ブラウザとApacheの間は443番のHTTPSで暗号化し、同じサーバー内のApacheからTomcatへは8080番のHTTPで渡します。証明書の管理がApacheの1か所で済み、Tomcat側にはSSLの設定が要りません。
# HTTPはHTTPSへリダイレクト
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
# 証明書(Let's Encryptの例)
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# HTTPSで受けたことをTomcatに伝える
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On
ProxyPass /app/ http://127.0.0.1:8080/app/
ProxyPassReverse /app/ http://127.0.0.1:8080/app/
</VirtualHost>
Ubuntu・Debian系ではsudo a2enmod ssl headersで、SSLとヘッダー操作のモジュールを有効にしておきます。
ここで大事なのがRequestHeader set X-Forwarded-Proto "https"の1行です。Tomcatから見ると、届くリクエストはApacheからのHTTPです。このままでは、アプリがリダイレクトするときにhttp://のURLを作ってしまい、「ログイン後にhttpへ飛ばされる」「リダイレクトが繰り返される」といったトラブルになります。
Tomcat側では、前の見出しで紹介したRemoteIpValveのprotocolHeader="X-Forwarded-Proto"がこのヘッダーを読み取り、リクエストを「HTTPSで来たもの」として扱います(request.isSecure()がtrueになります)。Spring Bootならserver.forward-headers-strategy=nativeの設定で同じように処理されます。
AJP(mod_jk・mod_proxy_ajp)が使われてきた背景
AJPは、バイナリ形式でデータをやり取りする専用プロトコル。HTTPよりもデータ量が少なく済むため、回線が細かった時代には重宝されました。
しかし、設定が複雑で、古いライブラリの管理も面倒というデメリットがあります。
今となっては通信速度も十分速いので、あえてこれを選ぶ理由は少なくなりました。
昔の職場のレガシーシステムでこれを見たときは、設定の難解さにめまいがしたものです。
mod_proxy_ajpで連携する設定例とsecret(Ghostcat対策)
既存システムの都合でAJPを使う場合は、2020年に公表された脆弱性「Ghostcat(CVE-2020-1938)」を前提に設定する必要があります。
この脆弱性を受けて、Tomcat 9.0.31・8.5.51以降ではAJPコネクタの初期設定が強化されました。AJPコネクタは初期状態で無効、有効化しても待ち受けはループバックアドレスのみ、さらにsecretRequiredが既定でtrueとなり、secretを設定しないと起動しません。
<!-- Tomcat側:conf/server.xml(初期状態ではコメントアウトされている) -->
<Connector protocol="AJP/1.3"
address="127.0.0.1"
port="8009"
redirectPort="8443"
secret="長くて推測されにくい文字列" />
Apache側では、httpd 2.4.42以降であればProxyPassの末尾にsecret=を付けて同じ文字列を渡せます。
# Apache側(httpd 2.4.42以降):Tomcatと同じsecretを渡す
ProxyPass /app/ ajp://127.0.0.1:8009/app/ secret=長くて推測されにくい文字列
ProxyPassReverse /app/ ajp://127.0.0.1:8009/app/
古い記事で見かけるsecretRequired="false"で逃げる設定は、公式ドキュメントでも「信頼できるネットワークで使う場合に限る」とされています。バージョンアップ後にAJPが起動しなくなった場合も、まずはsecretを揃える方向で対処しましょう。
Tomcatを複数台に振り分ける:mod_proxy_balancerとセッション維持
アクセスが増えてきたら、Apacheの後ろにTomcatを複数台並べて負荷を分散できます。これもApacheを前に置く大きな理由の1つです。使うのはmod_proxy_balancerです。
# Ubuntu・Debian系: sudo a2enmod proxy_balancer lbmethod_byrequests slotmem_shm
<Proxy "balancer://tomcats">
BalancerMember "http://10.0.0.11:8080" route=tomcat1
BalancerMember "http://10.0.0.12:8080" route=tomcat2
ProxySet stickysession=JSESSIONID|jsessionid
</Proxy>
ProxyPass "/app/" "balancer://tomcats/app/"
ProxyPassReverse "/app/" "balancer://tomcats/app/"
注意したいのがログイン状態(セッション)です。Tomcatはセッションを各サーバーのメモリに持つため、リクエストのたびに別のTomcatへ振られると、ログインが切れてしまいます。
そこで使うのがスティッキーセッションです。各Tomcatのserver.xmlでEngineにjvmRouteを付けると、セッションIDの末尾に「.tomcat1」のような目印が付きます。Apacheはこの目印とrouteを照らし合わせ、同じ利用者を同じTomcatへ送り続けます。
<!-- 1台目の conf/server.xml(2台目は jvmRoute="tomcat2") -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
ただし、スティッキーセッションでは、Tomcatが1台止まるとそのTomcatにいた利用者のセッションは失われます。止まっても引き継ぎたい場合は、Tomcatのクラスタ機能でセッションを複製するか、Spring Session+Redisのようにセッションを外部に置く構成を検討します。
なお、Tomcatを別サーバーに置く構成では、HTTPコネクタのaddressは127.0.0.1ではなく内部ネットワーク側のIPアドレスにし、ファイアウォールでApacheのサーバーからだけ8080番に届くようにします。
どの連携方式を選ぶべきかの判断基準
どれを使うか迷ったら、基本的には「新しい・簡単・安全」の3拍子が揃ったものを選びましょう。私の独断と偏見による判断基準をお伝えします。
初心者がまず選ぶならmod_proxyな理由
圧倒的に情報量が多く、設定ミスが起きにくいからです。
何かトラブルが起きたとき、ブラウザでTomcatに直接アクセスして動くか確認できるのも強み。
AJPだと専用ツールが必要だったりして、切り分けに時間がかかります。
まずはmod_proxyで「動く喜び」を味わってから、必要に応じて深い沼にハマりましょう。
AJP連携を検討するケースと注意点
「どうしても既存のシステムがAJPで動いている」場合や、極限までパケットサイズを削らなければならない特殊な環境。
そんなとき以外は、あえて選ぶ必要はありません。
もし使うなら、セキュリティ設定(secretオプションなど)をしっかり行わないと、脆弱性の標的になるので注意が必要です。
正直、今の時代にAJPを新規導入するのは、マニュアル車をあえて選ぶようなこだわり(あるいは苦行)に近いかもしれません。
将来の拡張や運用を見据えた考え方
システムは作って終わりではありません。数年後に別のサーバーに移管したり、クラウドへ移行したりする可能性があります。
その際、標準的なHTTPベースの連携にしておけば、引っ越し作業が楽になります。
特定の技術に依存しすぎない「ポータビリティ」を意識することが、未来の自分への最大のプレゼントになります。
連携構成でよく起きるトラブルとその原因
設定したのに動かない。これ、エンジニアあるあるです。私も何度PCを投げ出したくなったか分かりません。
連携できない?404・502エラーで疑うポイント
「404 Not Found」ならパスの設定ミス、「502 Bad Gateway」ならTomcatが死んでいるか、ポートが違います。
よくあるのが、SELinuxやファイアウォールが邪魔をしているケース。
設定ファイルばかり見ていて、実はOSのセキュリティ機能にブロックされていた……なんてオチは、私も通算10回は経験しています。
パフォーマンスが出ない構成の典型例
Tomcatの同時接続数(maxThreads)と、Apacheの接続数のバランスが悪いと詰まります。
Apacheが1,000件受け取れるのに、Tomcatが200件しか処理できない設定だと、入り口で大渋滞。これを「設定の不整合」と呼びます。
全体のキャパシティは、一番弱いところに引っ張られることを忘れないでください。
設定ミスが起きやすい箇所
URLの末尾に「/(スラッシュ)」を付けるか付けないか。これだけで挙動が変わります。
ProxyPass /app http://localhost:8080/app/ # これでハマる
こういう細かい部分で数時間を溶かすのがエンジニアの宿命ですが、ドキュメントをよく読めば防げます。動かないときは、まずスラッシュを疑いましょう(笑)。
パスを変えて転送するとログインやリンクが壊れる
「https://example.com/で公開したいけれど、Tomcatのアプリは/appで動いている」。こんなときに次のように書くと、トップページは表示されるのにログインが維持できない、リンクを押すと404になるといった症状が出ます。
ProxyPass / http://127.0.0.1:8080/app/
ProxyPassReverse / http://127.0.0.1:8080/app/
原因は、公開しているパス(/)とTomcat上のパス(コンテキストパス/app)の食い違いです。Tomcatはセッション用のCookieをPath=/appで発行するため、/で見ているブラウザはそのCookieを送り返しません。また、アプリが生成するHTML内のリンクは/app/…のままなので、/app/app/…のような存在しないURLになってしまいます。ProxyPassReverseが書き換えるのはリダイレクト先(Locationヘッダー)だけで、HTMLの中身は書き換えません。
対策は次のどれかです。上から順におすすめです。
- 公開パスとコンテキストパスを揃える:
/app/は/app/へ転送する。いちばんトラブルが少ない - アプリをルートで動かす:WARファイルを
ROOT.warという名前でデプロイすると、コンテキストパスが/になる - Cookieのパスだけ書き換える:
ProxyPassReverseCookiePath /app /を追加する。ただしHTML内のリンクの問題は残るので、アプリ側が相対パスで作られている場合に限られる
Tomcatが起動しない・日本語が化けるときの定番原因
連携以前に、Tomcat単体でつまずく定番のパターンも押さえておきましょう。まずはlogsフォルダのcatalina.outやlocalhost.日付.logを開き、次のメッセージが出ていないか確認します。
Address already in use:8080番を別のソフト(別のTomcatなど)が使っている。lsof -i :8080(Windowsはnetstat -ano | findstr :8080)で使用中のプロセスを調べ、止めるかポート番号を変えるNeither the JAVA_HOME nor the JRE_HOME environment variable is defined:Javaの場所がわからず起動できない。環境変数JAVA_HOMEを設定するか、setenv.shに書くClassNotFoundException・NoClassDefFoundError(javax/servlet/…):javax.*で書かれた古いアプリをTomcat 10以降で動かしている。jakarta.*に書き換えるか、Tomcat 9.0を使う
フォームから送った日本語が文字化けする場合は、POSTの文字コード指定が抜けていることがほとんどです。サーブレットでrequest.getParameter()を呼ぶ前にrequest.setCharacterEncoding("UTF-8")を実行するか、web.xmlでアプリ全体の文字コードを指定します。
<!-- WEB-INF/web.xml(Servlet 4.0以降=Tomcat 9.0以降で使える) -->
<request-character-encoding>UTF-8</request-character-encoding>
<response-character-encoding>UTF-8</response-character-encoding>
URLのクエリ文字列(GETのパラメータ)は、Tomcat 8.0以降は初期設定でUTF-8として扱われます。Spring Bootも標準でUTF-8に設定されるため、自分で指定する必要はありません。
Apache×Tomcat連携で押さえておくべき注意点
いざ本番へ、と意気込む前に。これだけは守ってほしい「エンジニアの約束」があります。
セキュリティ面で最低限考えること
Tomcatに直接外からアクセスできないよう、ファイアウォールで8080ポートを閉じましょう。
Apacheを通したアクセスだけに制限することで、脆弱性を突かれるリスクを最小限に抑えられます。
また、Apacheのバージョン情報を隠す(ServerTokens ProductOnly)のも、地味ですが大切なマナーです。
Tomcat側でも、本番前に次の3つは済ませておきましょう。
- 使わない初期アプリを消す:
webappsのdocs・examplesは本番では不要。manager・host-managerも使わないなら消し、使う場合は外部から開けないようにする - エラー画面にバージョンを出さない:初期設定のエラー画面には、Tomcatのバージョンや例外の詳細が表示される。
ErrorReportValveで非表示にする - 停止用ポートを見直す:Tomcatは停止命令を受けるために8005番を開いている(初期設定ではローカルからのみ)。systemdなどで停止する運用なら
port="-1"で無効にできる。ただしその場合shutdown.shは使えなくなる
<!-- conf/server.xml:停止用ポートを無効化 -->
<Server port="-1" shutdown="SHUTDOWN">
<!-- conf/server.xml:<Host> の中に追加(エラー画面の詳細とバージョンを隠す) -->
<Valve className="org.apache.catalina.valves.ErrorReportValve"
showReport="false" showServerInfo="false" />
ログの分散でハマらないための視点
ApacheのログとTomcatのログ、両方を見る癖をつけてください。
エラーが起きたとき、片方だけ見て「何も記録されていない!」と焦るのは新人の証。
リクエストのIDを共有する仕組みを作るなど、両方のログを突き合わせられるようにしておくと、調査スピードが10倍変わります。
本番運用を想定した設定の考え方
タイムアウト値の設定は、甘く見てはいけません。
Tomcatの処理が長引いたとき、Apacheがいつまで待つか。これを適切に設定しないと、特定の重い処理のせいで全ユーザーが待たされることになります。
「潔く諦める(タイムアウトさせる)」のも、システム全体の健康を守るためには必要です。
よくある質問
Q1. TomcatとApacheを連携させる理由は何ですか?
A1. 静的コンテンツの配信をApacheに任せてTomcatの負担を減らすこと、Apacheをリバースプロキシとして置くことでTomcatを直接外部に晒さずセキュリティを高めること、細かいセキュリティ設定をApache側で行えることが主な理由です。
Q2. mod_proxyとAJP、どちらを選ぶべきですか?
A2. 現在はmod_proxy(HTTPベース)が主流です。情報量が多く設定ミスが起きにくいため、初心者はまずmod_proxyを選びましょう。AJPは既存システムがAJPで動いている場合など特殊なケースでのみ検討します。
Q3. 502 Bad Gatewayが出る原因は何ですか?
A3. Tomcatが停止している、またはポート番号が間違っている場合に発生します。まずTomcatが起動しているか、Apacheの設定で指定したポートとTomcatの待ち受けポートが一致しているかを確認しましょう。
Q4. Apacheのモジュールを有効化するにはどうすればいいですか?
A4. Ubuntu/Debian系ならsudo a2enmod proxyとsudo a2enmod proxy_httpを実行し、Apacheを再起動します。
Q5. TomcatのポートをApache経由に統一するセキュリティ上のメリットは?
A5. ファイアウォールで8080ポートへの外部アクセスを閉じ、Apache経由のアクセスのみに制限することで、Tomcatの脆弱性が直接狙われるリスクを最小限に抑えられます。
Q6. Tomcatとは何ですか?
A6. JavaサーブレットやJSPを実行するためのオープンソースのサーブレットコンテナです。Javaで作ったWebアプリを、ブラウザから使える状態にする土台の役割を担います。
Q7. Tomcatは無料で使えますか?
A7. はい、完全に無料です。Apache License 2.0のオープンソースソフトウェアなので、商用利用もライセンス費用なしで可能です。
Q8. Tomcat単体でもWebサーバーとして動きますか?
A8. 簡易的なWebサーバー機能も持っているので、Tomcat単体でもWebサイトを公開できます。ただし静的コンテンツの大量配信はApacheやNginxの方が得意なため、現場では連携構成が定番です。
Q9. Tomcatの「Catalina」とは何ですか?
A9. Tomcatの中でサーブレットを実行する中核部分(サーブレットコンテナ)の名前です。インストール先を示す環境変数CATALINA_HOMEや、ログファイルのcatalina.outなど、現場では頻繁に目にする名前です。
Q10. Spring BootでもTomcatの知識は必要ですか?
A10. 必要です。Spring BootにはTomcatが内蔵されており、ポート設定やエラーの切り分けにはTomcatの基礎知識がそのまま役立ちます。
Q11. サーブレットとJSPの違いは何ですか?
A11. サーブレットはリクエストを受けて処理を行うJavaプログラム(処理担当)、JSPはHTMLの中にJavaを埋め込んで画面を作る仕組み(見た目担当)です。JSPも実行時にはTomcatがサーブレットに変換して動かすため、最終的にはどちらもサーブレットとして動きます。
Q12. JSPは今でも使われていますか?
A12. 新規開発ではThymeleafなどのテンプレートエンジンや、フロントエンドとAPIを分ける構成が主流で、JSPはあまり選ばれません。ただしJSPで作られた既存システムは多く、保守の現場では今も読めることが求められます。
この記事を読んだあとに取るべき次の一手
理屈はわかった。あとは手を動かすだけ。あなたが今日からできるアクションを提案します。
小規模環境でまず試すなら何をすべきか
まずは自分のPCのVM(VirtualBoxなど)や、安いVPSでApacheとTomcatを入れてみてください。
そしてmod_proxyで一行書いて、Tomcatの「猫」の画面が表示されるか確認しましょう。
あの画面が出た瞬間の達成感は、何度味わってもいいものです。まずは「最小構成」を自力で作ることが、最大の学びになります。
実務で使うなら追加で学ぶべきポイント
最小構成が動いたら、この記事で紹介した「HTTPS化」と「負荷分散」を実際に組んでみましょう。
Apache一台の後ろにTomcatを二台並べてみる。あるいは、Let's Encryptで証明書を入れてみる。
これができれば、あなたは現場で「インフラもわかるJavaエンジニア」として重宝されるはずです。
私も最初はチンプンカンプンでしたが、一つずつ繋いでいくうちに、パズルが解けるような楽しさに変わりました。
あなたもぜひ、この「連携の美学」を楽しんでください。
| REV. | DATE | 内容 |
|---|---|---|
| 5 | 2026-10-15 | 図解を描き直し(図面のデザインにそろえた) |
| 4 | 2026-10-14 | 雰囲気だけの挿絵を外した |
| 3 | 2026-10-06 | 記載内容の事実確認と修正 |
| 2 | 2026-08-30 | 2026年8月時点の情報で全体を見直し |
| 1 | 2026-01-31 | 初版 |





