1. 项目概述

最近在部署Java Web应用时,我发现直接使用官方Tomcat镜像往往需要额外配置,于是决定自己动手制作一个定制化的Tomcat Docker镜像。这个项目主要解决三个痛点:一是官方镜像默认配置不够优化;二是每次部署都要重复配置环境;三是需要集成一些常用工具和监控组件。

2. 环境准备

2.1 基础镜像选择

我选择了 openjdk:8-jdk 作为基础镜像,主要考虑:

  • 与Tomcat 9的兼容性最佳
  • 体积比完整JDK镜像小约30%
  • 官方维护,安全性有保障
FROM openjdk:8-jdk

注意:如果使用Tomcat 10+,建议改用 openjdk:11-jdk 作为基础镜像

2.2 Tomcat版本选择

经过测试比较,最终选定Tomcat 9.0.65版本:

  • 稳定性:长期支持版本
  • 漏洞修复:已包含所有关键安全补丁
  • 特性支持:满足大多数Web应用需求

3. Dockerfile编写

3.1 基础配置

# 设置环境变量
ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
ENV TOMCAT_MAJOR 9
ENV TOMCAT_VERSION 9.0.65
ENV TOMCAT_TGZ_URL https://archive.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz

3.2 安装过程

RUN set -eux; \
    mkdir -p "$CATALINA_HOME"; \
    wget -O tomcat.tar.gz "$TOMCAT_TGZ_URL"; \
    tar -xvf tomcat.tar.gz --strip-components=1 -C "$CATALINA_HOME"; \
    rm tomcat.tar.gz; \
    chmod +x $CATALINA_HOME/bin/*.sh

3.3 优化配置

# 删除默认应用
RUN rm -rf $CATALINA_HOME/webapps/*

# 配置server.xml
COPY config/server.xml $CATALINA_HOME/conf/

# 设置JVM参数
ENV JAVA_OPTS="-server -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m"

4. 镜像优化技巧

4.1 多阶段构建

# 构建阶段
FROM maven:3.6.3-jdk-8 AS builder
COPY . /build
WORKDIR /build
RUN mvn clean package

# 运行阶段
FROM openjdk:8-jdk
COPY --from=builder /build/target/*.war $CATALINA_HOME/webapps/ROOT.war

4.2 镜像瘦身

  1. 使用 .dockerignore 文件排除不必要的文件
  2. 合并RUN指令减少镜像层
  3. 清理apt缓存和临时文件

5. 常见问题解决

5.1 启动超时问题

Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds

解决方案:

  1. 增加启动超时时间
  2. 检查应用依赖是否完整
  3. 查看catalina.out日志定位具体问题

5.2 中文乱码问题

在Dockerfile中添加:

ENV LANG C.UTF-8

5.3 权限问题

RUN chown -R www-data:www-data $CATALINA_HOME
USER www-data

6. 镜像发布与使用

6.1 构建命令

docker build -t my-tomcat:9.0.65 .

6.2 运行容器

docker run -d \
  -p 8080:8080 \
  -v /path/to/logs:/usr/local/tomcat/logs \
  -v /path/to/webapps:/usr/local/tomcat/webapps \
  --name my-tomcat \
  my-tomcat:9.0.65

6.3 健康检查

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/ || exit 1

7. 高级配置

7.1 集成APM监控

# 安装SkyWalking Agent
COPY skywalking-agent/ /opt/skywalking-agent/
ENV SW_AGENT_NAME=your-application-name
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
ENV JAVA_OPTS="$JAVA_OPTS -javaagent:/opt/skywalking-agent/skywalking-agent.jar"

7.2 日志收集配置

# 配置log4j2
COPY config/log4j2.xml $CATALINA_HOME/conf/
ENV LOGGING_CONFIG="-Dlog4j.configurationFile=$CATALINA_HOME/conf/log4j2.xml"

8. 安全加固

8.1 禁用管理界面

RUN rm -rf $CATALINA_HOME/webapps/manager \
    && rm -rf $CATALINA_HOME/webapps/host-manager

8.2 修改默认端口

EXPOSE 8888

8.3 设置非root用户

RUN groupadd -r tomcat && useradd -r -g tomcat tomcat
USER tomcat

9. 持续集成方案

9.1 Jenkins流水线示例

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'docker build -t my-tomcat:${BUILD_NUMBER} .'
            }
        }
        stage('Test') {
            steps {
                sh 'docker run --rm my-tomcat:${BUILD_NUMBER} /bin/bash -c "curl -I http://localhost:8080"'
            }
        }
        stage('Deploy') {
            steps {
                sh 'docker tag my-tomcat:${BUILD_NUMBER} registry.example.com/my-tomcat:latest'
                sh 'docker push registry.example.com/my-tomcat:latest'
            }
        }
    }
}

10. 性能调优建议

10.1 JVM参数优化

ENV JAVA_OPTS="-server \
    -Xms1g -Xmx2g \
    -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
    -XX:+UseG1GC \
    -XX:MaxGCPauseMillis=200 \
    -XX:ParallelGCThreads=4 \
    -XX:ConcGCThreads=2"

10.2 Tomcat连接器配置

<Connector port="8080" protocol="HTTP/1.1"
           maxThreads="200"
           minSpareThreads="25"
           acceptCount="100"
           connectionTimeout="20000"
           compression="on"
           compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript"/>

11. 监控方案

11.1 Prometheus监控配置

# 添加JMX Exporter
COPY jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar /opt/jmx_exporter/
COPY jmx_exporter/tomcat.yml /opt/jmx_exporter/
ENV JAVA_OPTS="$JAVA_OPTS -javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.16.1.jar=8081:/opt/jmx_exporter/tomcat.yml"

11.2 暴露监控端口

EXPOSE 8080 8081

12. 最佳实践总结

  1. 版本固定 :始终指定确切的Tomcat和JDK版本号
  2. 最小化镜像 :只包含必要的组件和文件
  3. 配置分离 :将可变配置通过环境变量或volume挂载
  4. 安全加固 :使用非root用户运行,禁用不必要的功能
  5. 监控集成 :内置健康检查和性能监控
  6. 日志处理 :确保日志可以持久化和集中收集

在实际生产环境中,我建议将这套方案与CI/CD流水线集成,实现自动化构建、测试和部署。对于高并发场景,还需要根据实际负载情况调整JVM和Tomcat参数。

更多推荐