1. 为什么在 Debian 10 上亲手部署 Tomcat 9 仍是运维和开发者的必修课
Apache Tomcat 9 是 Java Web 应用最主流的轻量级 Servlet 容器,而 Debian 10(代号 Buster)作为长期支持(LTS)发行版,至今仍被大量生产环境、教育机构和中小型企业稳定使用。你可能在想:现在不是有 Docker、Kubernetes、云平台一键部署了吗?为什么还要花时间手动装 Tomcat?我做过三年 Java 后端支撑,也带过十几支高校实训团队,实打实踩过坑才明白——Docker 镜像再方便,一旦应用启动报错 java.lang.ClassNotFoundException: javax.servlet.http.HttpServletRequest ,或者日志里反复出现 SEVERE [main] org.apache.catalina.startup.Catalina.start The required Server component failed to start ,没有亲手摸过 $CATALINA_HOME/conf/server.xml 的结构、没改过 catalina.sh 的 JVM 参数、没查过 logs/catalina.out 的第一行启动堆栈,你连问题出在“是 JDK 版本不兼容”还是“ /usr/lib/jvm 路径被硬编码覆盖”都分不清。Debian 10 默认源里的 tomcat9 包虽然能 apt install 一键装上,但它把二进制、配置、Web 应用目录全打散到 /usr/share/tomcat9 、 /etc/tomcat9 、 /var/lib/tomcat9 三个独立路径,连 CATALINA_HOME 和 CATALINA_BASE 的概念都被抽象掉了。而绝大多数 Java 开发者本地调试用的是官方二进制包解压模式,线上部署也要求路径清晰、权限可控、升级可回滚。所以,这篇内容不是教你怎么“点几下鼠标”,而是带你从零开始,在一台干净的 Debian 10 系统上,用官方 Apache 发布的 .tar.gz 包,完整复现一个生产就绪(production-ready)的 Tomcat 9 部署流程——包括 JDK 11 的精准匹配、用户隔离与权限最小化、systemd 服务的健壮封装、HTTPS 证书的嵌入式配置,以及最关键的:如何让 manager 和 host-manager 这两个高危管理界面只对内网 IP 开放,而不是裸奔在 8080 端口上任人扫描。它适合三类人:刚转 Java 的运维新手(需要理解容器底层逻辑)、正在备考 RHCE 或 LPIC-2 的 Linux 工程师(Tomcat 是典型 Java 中间件考题)、以及高校教师或实训导师(学生必须亲手敲命令才能建立系统直觉)。接下来所有步骤,我都已在 VirtualBox + Debian 10.13 最小化安装镜像中逐条验证,命令可直接复制粘贴,但更重要的是每一步背后的“为什么”。
2. 整体设计思路与关键决策依据
2.1 为什么坚持用官方二进制包而非 APT 源安装
Debian 10 官方仓库确实提供了 tomcat9 元包,执行 sudo apt install tomcat9 即可完成安装。但这个方案在真实生产环境中存在四个不可忽视的硬伤,我在为某省级政务云迁移旧系统时就因此返工两次:
第一, 版本锁定与更新滞后 。Debian 10 的 tomcat9 包固定为 9.0.31(2020 年初发布),而 Apache 官方 Tomcat 9 的最新稳定版已是 9.0.87(2024 年 3 月发布)。两者相差 56 个小版本,意味着缺失了超过 200 个安全补丁(CVE-2021-25122、CVE-2022-25762 等关键漏洞均未修复)和性能优化(如 NIO2 connector 的线程池改进)。APT 源不会主动推送这些更新,你得等 Debian 维护者手动打包并审核,平均周期长达 6–12 个月。
第二, 目录结构违背 Tomcat 原生约定 。官方包将 bin/ 放在 /usr/share/tomcat9/bin , conf/ 放在 /etc/tomcat9/ , webapps/ 放在 /var/lib/tomcat9/webapps 。这直接破坏了 CATALINA_HOME (指向二进制和库)与 CATALINA_BASE (指向配置和数据)的分离原则。当你需要在同一台服务器运行多个 Tomcat 实例(例如测试环境和预发环境共存)时,APT 方案会强制你复制整个 /etc/tomcat9 目录并手动修改所有路径引用,极易出错。而官方 .tar.gz 包解压后天然就是 CATALINA_HOME == CATALINA_BASE ,后续通过软链接或独立目录轻松实现多实例隔离。
第三, JVM 参数控制粒度粗放 。APT 包的启动脚本 /usr/libexec/tomcat9/tomcat9 将 -Xms 、 -Xmx 等参数硬编码在 /etc/default/tomcat9 中,且默认值仅为 256m 。对于一个承载 Spring Boot 微服务的 Tomcat,这点内存连应用本身都加载不完。更麻烦的是,它把 JAVA_HOME 强制绑定到 /usr/lib/jvm/default-java ,而 Debian 10 默认的 default-java 指向 OpenJDK 11,但某些老系统依赖 Oracle JDK 8,APT 方案无法优雅切换。
第四, 管理界面权限模型僵化 。APT 安装后, manager 和 host-manager 的访问控制由 /etc/tomcat9/tomcat-users.xml 配置,但其 RemoteAddrValve 过滤器默认未启用,导致只要知道用户名密码,外网任何 IP 都能访问。而官方包允许你在 conf/context.xml 中精细定义 <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1|192\.168\.1\.\d+" /> ,这是生产环境的底线要求。
因此,我的设计核心是: 以 Apache 官方二进制包为唯一可信来源,严格遵循上游文档规范,用 Linux 原生机制(systemd、useradd、chown)构建最小权限模型,拒绝任何 Debian 特有的抽象层 。这不是为了炫技,而是为了确保你的部署行为与 Apache 官网文档、Stack Overflow 高票答案、以及同事的本地开发环境完全一致——当问题发生时,你能直接搜索 “Tomcat 9.0.87 debian 10 bind address failed”,而不是陷入 “Debian tomcat9 package not starting” 这种模糊关键词的泥潭。
2.2 为什么选择 JDK 11 而非 JDK 8 或 JDK 17
Tomcat 9 官方明确声明支持 Java 8、Java 9、Java 10、Java 11,但不支持 Java 12 及以上版本(Tomcat 10 才开始支持 Jakarta EE 9+,即 jakarta.* 命名空间)。这是一个常被忽略的关键兼容性断点。很多教程盲目推荐 JDK 17,结果 catalina.sh start 后 ps aux | grep java 显示进程瞬间退出,日志里只有 UnsupportedClassVersionError —— 因为 Tomcat 9 编译目标是 Java 11 字节码,JDK 17 运行时无法向下兼容。
JDK 8 虽然被 Tomcat 9 支持,但它已于 2019 年 1 月结束公开更新(EOL),Oracle 不再提供安全补丁。Debian 10 的 openjdk-8-jdk 包虽仍在源中,但其最后更新停留在 2021 年(8u292),已知存在 CVE-2

384

被折叠的 条评论
为什么被折叠?



