Nginx + Tomcat 容器化实战:从零到一完成部署
前言
在之前的项目中,我基于五台虚拟机搭建了一套高可用架构(Keepalived + Nginx + Tomcat + MySQL)。随着容器化技术的普及,我决定将这些服务迁移到 Docker 中,实现更便捷的部署和管理。本文记录了将 Nginx 和 Tomcat 容器化的全过程,包括遇到的问题和解决方法,希望能为正在学习容器化的你提供参考。
环境准备
· 操作系统:Red Hat Enterprise Linux 9 (CentOS Stream 9) · Docker 版本:26.1.3 · 基础镜像:nginx:1.28.1、tomcat:11.0.18 · 项目文件:nginx.conf、tomcat.conf、testdb.jsp、server.xml
一、容器化 Nginx
1.1 准备配置文件
首先,将宿主机上 Nginx 的配置文件复制到工作目录:
mkdir -p /dockerdemo1 cp /etc/nginx/nginx.conf /dockerdemo1/ cp /etc/nginx/conf.d/tomcat.conf /dockerdemo1/ cd /dockerdemo1
1.2 编写 Dockerfile
创建一个名为 Dockerfile 的文件,内容如下:
FROM nginx:1.28.1 COPY nginx.conf /etc/nginx/nginx.conf COPY tomcat.conf /etc/nginx/conf.d/ EXPOSE 80
这里直接将宿主机的配置文件覆盖到镜像中,这样构建出的镜像就包含了我们自定义的配置。
1.3 构建镜像
docker build -t my-nginx:1.0 .
构建成功后,会显示镜像 ID。
1.4 运行测试容器
docker run -d -p 8080:80 --name nginx-test my-nginx:1.0
映射宿主机的 8080 端口到容器的 80 端口,方便测试。
1.5 验证
curl http://localhost:8080
如果看到 Nginx 欢迎页,说明容器运行正常。你也可以通过浏览器访问 http://宿主机IP:8080 查看效果。
问题记录:一开始我直接访问 localhost:8080 时,总是得到宿主机 Nginx 的页面,后来发现是宿主机 Nginx 也监听了 80 端口。通过 systemctl stop nginx 停止宿主机服务后,问题解决。这也提醒我们:容器化前最好先关闭冲突的服务。
二、容器化 Tomcat
2.1 准备文件
Tomcat 需要 JSP 文件和配置文件。我复制了项目中的 testdb.jsp 和自定义的 server.xml 到工作目录的 tomcat 子目录:
mkdir -p /dockerdemo1/tomcat cp testdb.jsp /dockerdemo1/tomcat/ cp server.xml /dockerdemo1/tomcat/ cd /dockerdemo1/tomcat
2.2 编写 Dockerfile
FROM tomcat:11.0.18 COPY testdb.jsp /usr/local/tomcat/webapps/ROOT/ COPY server.xml /usr/local/tomcat/conf/server.xml EXPOSE 8080
关键点:Tomcat 默认的 Web 应用根目录是 webapps/ROOT,必须将 JSP 文件放到这个目录下才能直接通过 /文件名 访问。
2.3 构建镜像
docker build -t my-tomcat:1.0 .
2.4 运行容器
为了避免与宿主机原有的 Tomcat 端口冲突,我将容器的 8080 映射到宿主机的 8081 端口:
docker run -d -p 8081:8080 --name tomcat-test my-tomcat:1.0
2.5 验证
curl http://localhost:8081/testdb.jsp
如果返回 JSP 页面的内容(即使数据库连接失败),说明 Tomcat 已经正确加载了 JSP 文件。
2.6 踩坑记录
问题 1:webapps/ROOT 被覆盖成文件
第一次编写 Dockerfile 时,我错误地写成了:
COPY testdb.jsp /usr/local/tomcat/webapps/ROOT
注意:目标路径末尾没有加斜杠,导致 Docker 将 testdb.jsp 直接复制成了名为 ROOT 的文件,覆盖了原本的 ROOT 目录。正确的写法应该是 /usr/local/tomcat/webapps/ROOT/(以斜杠结尾,表示这是一个目录),或者指定完整文件名 /usr/local/tomcat/webapps/ROOT/testdb.jsp。
问题 2:大小写敏感
另一个常见错误是路径大小写。Tomcat 的根目录名是 ROOT(全大写),如果写成 Root 或 root,也会导致文件放错位置,Tomcat 找不到页面而返回 404。
问题 3:镜像标签不存在
拉取基础镜像时,tomcat:11.0.18 可能不存在,需要加上 -jdk21 或 -jre21 等后缀。建议先搜索官方仓库确认可用标签:
docker search tomcat docker pull tomcat:11.0.18-jdk21
问题 4:网络问题导致拉取失败
在国内网络环境下,Docker Hub 访问不稳定。配置镜像加速器是关键:
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
]
}
配置后务必重启 Docker:
sudo systemctl daemon-reload sudo systemctl restart docker
三、验证容器间的网络连通(可选)
如果你已经将 Nginx 和 Tomcat 都容器化,并希望它们能够互相通信(例如 Nginx 反向代理到 Tomcat),可以通过创建自定义网络实现:
docker network create mynet docker run -d --net mynet --name nginx-container my-nginx:1.0 docker run -d --net mynet --name tomcat-container my-tomcat:1.0
然后在 Nginx 配置文件中将 proxy_pass 指向 tomcat-container:8080,因为同一个网络内容器名可以作为主机名直接访问。
四、总结
通过本次实践,我成功将原本在虚拟机中手动配置的 Nginx 和 Tomcat 服务容器化。整个过程并不复杂,核心在于:
· 理解基础镜像的使用 · 正确复制配置文件到指定路径 · 注意目录和文件名的拼写
容器化带来了极大的便利:不再需要手动安装软件、配置环境,一条 docker run 命令就能启动完整服务,并且可以轻松分享给他人。
更多推荐
所有评论(0)