What's?
Apache Tomcatには、公式のDockerイメージがあります。
現時点でのApache Tomcatの最新バージョンは11ですが、ここで使われているOpenJDKディストリビューションはEclipse Temurinのみです。
今回はAmazon CorrettoをベースイメージにしたApache TomcatのDockerイメージを作ってみたいと思います。
どうしてEclipse Temurinのみなの?
実際にDockerイメージを作る前に、Apache TomcatのDockerイメージがどうしてEclpse Temurinのみなのか少し見てみました。
ちなみに、Apache Tomcat 9.0まではAmazon Correttoを使ったDockerイメージもあったんですよね。
実はApache Tomcat 10.0.27まではAmazon CorrettoのDockerイメージもあったようです。
ではどうしてないのかというと、Amazon Correttoや他のディストリビューションのJDK/JREを組み合わせてDockerイメージを作成すると、パターンが膨大になりすぎて制御不能になるから、だそうです。
というわけで、Amazon Correttoを使ったApache TomcatのDockerイメージが再度出てくる可能性はかなり低いのではないかなと思います。
参考にするもの
では、Amazon Correttoを使ったApache TomcatのDockerイメージを作りたいわけですが、参考にするのはこちらのGitHubリポジトリでしょう。
今回は、現在リリースされているJakarta EE 10に対応するApache Tomcat 10.1を対象に考えたいと思います。
JDK、JRE(11、17、21)とUbuntu Linux 22.04 LTS、24.04 LTSの4つの組み合わせの選択肢がありますが、今回はJDK 21、Ubuntu Linux 24.04 LTSのDockerfile
を参考にしたいと思います。
この中身を見ると、やっていることは以下ですね。
- curlやSSL証明書のインストール
- Apache Tomcatのダウンロード
- ダウンロードしたファイルの検証
-
.bat
ファイルの削除 - デフォルトの
webapps
ディレクトリの退避 - Apache Tomcatのネイティブライブラリのビルドに必要なライブラリのインストール
- Apache Tomcatのネイティブライブラリのビルド
- shebangの
#!/bin/sh
を#!/usr/bin/env bash
に書き換え -
CMD ["catalina.sh", "run"]
で起動設定
ちなみに、catalina.sh
をrun
で実行するとApache Tomcatがフォアグラウンドで起動します。
一方で、ベースにするのはAmazon CorrettoのDockerイメージです。
環境
今回の環境はこちらです。
$ docker version
Client: Docker Engine - Community
Version: 28.0.0
API version: 1.48
Go version: go1.23.6
Git commit: f9ced58
Built: Wed Feb 19 22:11:04 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 28.0.0
API version: 1.48 (minimum version 1.24)
Go version: go1.23.6
Git commit: af898ab
Built: Wed Feb 19 22:11:04 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.7.25
GitCommit: bcc810d6b9066471b0b6fa75f557a15a1cbf31bb
runc:
Version: 1.2.4
GitCommit: v1.2.4-0-g6c52b3f
docker-init:
Version: 0.19.0
GitCommit: de40ad0
$ java --version
openjdk 21.0.6 2025-01-21
OpenJDK Runtime Environment (build 21.0.6+7-Ubuntu-124.04.1)
OpenJDK 64-Bit Server VM (build 21.0.6+7-Ubuntu-124.04.1, mixed mode, sharing)
$ mvn --version
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /home/charon/.sdkman/candidates/maven/current
Java version: 21.0.6, vendor: Ubuntu, runtime: /usr/lib/jvm/java-21-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-53-generic", arch: "amd64", family: "unix"
Amazon Corretto 21をベースイメージにした、Apache Tomcat 10.1のDockerイメージを作る
それでは、Amazon Corretto 21をベースイメージにした、Apache Tomcat 10.1のDockerイメージを作っていきます。
今回は以下のことをやってみましょう。
- Amazon Corretto 21をベースイメージにした、Apache Tomcat 10.1のDockerイメージを作る
- 作ったDockerイメージに対して簡単なWebアプリケーション(Jakarta Servletのみ)をデプロイする
- 作ったDockerイメージをベースにJib Maven PluginでDockerイメージを作成し、簡単なWebアプリケーション(Jakarta Servletのみ)をデプロイする
Dockerイメージを作る
まずはDockerイメージを作ります。
作成したDockerfile
はこちらです。
FROM amazoncorretto:21.0.6-al2023
# FROM amazoncorretto:21.0.6-al2023-headless
ENV CATALINA_HOME=/usr/local/tomcat
ENV PATH=$CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME
ENV TOMCAT_MAJOR=10
ENV TOMCAT_VERSION=10.1.36
RUN dnf install -y \
tar \
gzip \
findutils \
&& dnf autoremove -y \
&& dnf clean all \
&& rm -rf /var/cache/dnf \
&& curl -s -L https://dlcdn.apache.org/tomcat/tomcat-${TOMCAT_MAJOR}/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz -o tomcat.tar.gz \
&& tar xf tomcat.tar.gz --strip-components=1 \
&& rm bin/*.bat \
&& rm tomcat.tar.gz \
&& mv webapps webapps.dist \
&& mkdir webapps \
&& find bin -name '*.sh' -exec sed -ri 's|^#!/bin/sh$|#!/usr/bin/env bash|' '{}' + \
&& chmod -R +rX . \
&& chmod 1777 logs temp work
EXPOSE 8080
ENTRYPOINT []
CMD ["catalina.sh", "run"]
ベースイメージはこちらにしましたが、お好みでheadlessでもいいと思います。
FROM amazoncorretto:21.0.6-al2023
# FROM amazoncorretto:21.0.6-al2023-headless
あとは、オリジナルから以下の部分を引っ張ってきています。ネイティブライブラリは今回は端折りました。
- Apache Tomcatのダウンロード
-
.bat
ファイルの削除 - デフォルトの
webapps
ディレクトリの退避 - shebangの
#!/bin/sh
を#!/usr/bin/env bash
に書き換え -
CMD ["catalina.sh", "run"]
で起動設定
ビルド。
$ docker image build -t charon/tomcat:10.1.36-corretto-21.0.6-al2023 .
起動。
$ docker container run -it --rm --name tomcat charon/tomcat:10.1.36-corretto-21.0.6-al2023
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/lib/jvm/java-21-amazon-corretto
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
22-Feb-2025 08:02:44.782 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/10.1.36
22-Feb-2025 08:02:44.784 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Feb 13 2025 13:13:30 UTC
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 10.1.36.0
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 6.8.0-53-generic
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/lib/jvm/java-21-amazon-corretto.x86_64
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 21.0.6+7-LTS
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Amazon.com Inc.
22-Feb-2025 08:02:44.785 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat
22-Feb-2025 08:02:44.786 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat
22-Feb-2025 08:02:44.797 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
22-Feb-2025 08:02:44.797 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
22-Feb-2025 08:02:44.797 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
22-Feb-2025 08:02:44.797 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
22-Feb-2025 08:02:44.797 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dsun.io.useCanonCaches=false
22-Feb-2025 08:02:44.797 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
22-Feb-2025 08:02:44.797 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
22-Feb-2025 08:02:44.798 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
22-Feb-2025 08:02:44.798 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED
22-Feb-2025 08:02:44.798 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED
22-Feb-2025 08:02:44.798 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
22-Feb-2025 08:02:44.798 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
22-Feb-2025 08:02:44.798 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
22-Feb-2025 08:02:44.798 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
22-Feb-2025 08:02:44.804 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The Apache Tomcat Native library which allows using OpenSSL was not found on the java.library.path: [/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib]
22-Feb-2025 08:02:44.966 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
22-Feb-2025 08:02:44.978 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [339] milliseconds
22-Feb-2025 08:02:45.003 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
22-Feb-2025 08:02:45.004 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/10.1.36]
22-Feb-2025 08:02:45.026 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
22-Feb-2025 08:02:45.032 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [53] milliseconds
OKですね。
サイズはこれくらいです。headlessにすると100Mくらい減ります。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
charon/tomcat 10.1.36-corretto-21.0.6-al2023 a06526270d06 4 seconds ago 512MB
アプリケーションをデプロイしてみる
簡単なアプリケーションをJakarta Servletで作成してデプロイしてみましょう。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>simple-servlet</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>ROOT</finalName>
</build>
</project>
package com.example;
import java.io.IOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@WebServlet("/")
public class SimpleServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String word = request.getParameter("word");
response.getWriter().printf("Hello %s!!%n", word);
}
}
パッケージング。
$ mvn package
作成したApache Tomcatのイメージにデプロイしてみます。
$ docker container run -it --rm --name tomcat -p 8080:8080 -v $(pwd)/target/ROOT.war:/usr/local/tomcat/webapps/ROOT.war charon/tomcat:10.1.36-corretto-21.0.6-al2023
確認。
$ curl 'localhost:8080?word=Tomcat'
Hello Tomcat!!
Jib Maven Pluginで使ってみる
最後はJib Maven Pluginで使ってみます。
サンプルのJakarta Servletは先ほどのものと同じものを使います。
pom.xml
にはJib Maven Pluginの設定を追加しました。
<build>
<finalName>ROOT</finalName>
<plugins>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.4.4</version>
<configuration>
<from>
<image>docker://charon/tomcat:10.1.36-corretto-21.0.6-al2023</image>
</from>
<to>
<image>charon/${project.artifactId}</image>
</to>
<container>
<appRoot>/usr/local/tomcat/webapps/ROOT</appRoot>
</container>
</configuration>
</plugin>
</plugins>
</build>
ベースイメージはDockerデーモンから取得します。
<from>
<image>docker://charon/tomcat:10.1.36-corretto-21.0.6-al2023</image>
</from>
ビルド。
$ mvn package jib:dockerBuild
できました。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
charon/tomcat 10.1.36-corretto-21.0.6-al2023 a06526270d06 21 minutes ago 512MB
charon/simple-servlet latest fab577535542 55 years ago 512MB
起動。
$ docker container run -it --rm --name tomcat -p 8080:8080 charon/simple-servlet:latest
動作確認。
$ curl 'localhost:8080?word=Tomcat'
Hello Tomcat!!
よさそうですね。