1. 环境准备与基础概念
在开始部署Nginx和Tomcat之前,我们需要先搭建好基础环境。我选择在WSL(Windows Subsystem for Linux)环境中使用Docker,这是目前Windows平台上最接近原生Linux体验的开发环境。
1.1 WSL与Docker环境配置
WSL2提供了完整的Linux内核支持,是运行Docker的理想选择。安装步骤如下:
- 启用WSL功能(以管理员身份运行PowerShell):
bash复制dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
- 安装Linux发行版(推荐Ubuntu)后,升级到WSL2:
bash复制wsl --set-version Ubuntu 2
- 安装Docker Desktop for Windows时,确保勾选"Use WSL 2 based engine"选项。这样Docker会直接与WSL2集成,无需额外配置。
注意:如果遇到网络问题,建议检查Windows防火墙设置,或者尝试更换Docker的镜像源为国内镜像。
1.2 Docker核心概念回顾
理解以下几个核心概念对后续操作至关重要:
- 镜像(Image):只读模板,包含运行应用所需的所有文件和配置。比如Nginx镜像就包含了Nginx服务器和其运行环境。
- 容器(Container):镜像的运行实例,可以被启动、停止、删除。每个容器都是相互隔离的。
- 仓库(Repository):存放镜像的地方,Docker Hub是最大的公共仓库。
常用命令速记:
bash复制# 镜像相关
docker pull [镜像名] # 拉取镜像
docker images # 查看本地镜像
docker rmi [镜像ID] # 删除镜像
# 容器相关
docker run [参数] [镜像] # 创建并启动容器
docker ps -a # 查看所有容器
docker stop [容器ID] # 停止容器
docker rm [容器ID] # 删除容器
2. Nginx部署实战
2.1 拉取与运行Nginx镜像
Nginx是最流行的Web服务器之一,在Docker中部署非常简单:
bash复制docker pull nginx:latest
这个命令会从Docker Hub拉取最新的Nginx官方镜像。我推荐始终明确指定版本号(如nginx:1.25),而不是使用latest标签,这能确保环境的一致性。
2.2 端口映射的奥秘
直接运行docker run -d nginx确实能启动容器,但无法从宿主机访问。这是因为Docker容器有自己独立的网络栈,默认情况下,容器内部的80端口并没有映射到宿主机的任何端口。
正确的做法是使用-p参数进行端口映射:
bash复制docker run -d -p 9999:80 --name my-nginx nginx
这个命令的含义是:
-d:后台运行容器-p 9999:80:将宿主机的9999端口映射到容器的80端口--name my-nginx:给容器起个有意义的名字,便于管理
常见问题:如果遇到端口冲突(比如9999已被占用),可以换用其他端口如8080、8888等。使用
netstat -tuln可以查看已占用的端口。
2.3 验证Nginx运行
成功运行后,可以通过以下方式验证:
- 浏览器访问
http://localhost:9999,应该能看到Nginx欢迎页面。 - 命令行验证:
bash复制curl http://localhost:9999
- 查看容器日志:
bash复制docker logs my-nginx
2.4 自定义Nginx配置
实际项目中,我们通常需要自定义Nginx配置。有两种推荐方式:
方法一:挂载配置文件
bash复制docker run -d -p 9999:80 \
-v /path/to/nginx.conf:/etc/nginx/nginx.conf \
-v /path/to/html:/usr/share/nginx/html \
nginx
方法二:基于官方镜像构建新镜像
dockerfile复制FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY ./html /usr/share/nginx/html
经验分享:生产环境推荐使用方法二,因为所有配置都打包在镜像中,部署更可靠。开发环境可以使用方法一,便于快速修改配置。
3. Tomcat部署深度解析
3.1 拉取指定版本的Tomcat镜像
Tomcat作为Java Web应用服务器,版本选择很重要。不同版本的Tomcat对应不同的JDK要求:
bash复制# 拉取特定版本的Tomcat
docker pull tomcat:9.0.115-jre8-temurin-noble
这个镜像包含了:
- Tomcat 9.0.115
- Eclipse Temurin JRE 8(原AdoptOpenJDK)
- Ubuntu Noble基础系统
版本选择建议:生产环境应选择长期支持(LTS)版本,如Tomcat 10.1.x或9.0.x系列,并确保与JDK版本兼容。
3.2 解决404问题的根本原因
直接运行Tomcat容器后访问出现404,这是因为官方Tomcat镜像为了保持精简,移除了webapps目录下的默认应用。深入分析容器内部结构:
bash复制docker exec -it my-tomcat bash
ls -l /usr/local/tomcat/webapps*
你会发现:
webapps/:空目录webapps.dist/:包含完整的管理应用和示例
解决方案是将webapps.dist内容复制到webapps:
bash复制docker exec my-tomcat sh -c 'cp -r /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps/'
3.3 持久化部署的Web应用
实际项目中,我们通常需要部署自己的WAR包。推荐做法:
bash复制docker run -d -p 8081:8080 \
-v /path/to/your/app.war:/usr/local/tomcat/webapps/app.war \
tomcat:9.0
或者使用Dockerfile构建自定义镜像:
dockerfile复制FROM tomcat:9.0
COPY target/your-app.war /usr/local/tomcat/webapps/
重要提示:Tomcat会自动解压WAR文件。如果希望保留WAR文件不被解压,可以放在
webapps/目录外的其他位置,然后在server.xml中配置Context。
3.4 Tomcat性能调优建议
在Docker中运行Tomcat时,需要注意以下性能相关配置:
- 内存设置:
bash复制docker run -d -p 8081:8080 \
-e JAVA_OPTS="-Xms512m -Xmx1024m" \
tomcat:9.0
- 连接器优化:
在conf/server.xml中调整Connector参数:
xml复制<Connector port="8080" protocol="HTTP/1.1"
maxThreads="200"
minSpareThreads="10"
connectionTimeout="20000"
redirectPort="8443" />
- 关闭不需要的应用:删除webapps目录下的examples、docs等不需要的应用,减少安全风险。
4. 镜像构建与定制化
4.1 使用commit创建自定义镜像
当你对容器做了修改(如解决了Tomcat的404问题),可以将其保存为新镜像:
bash复制docker commit -a "Your Name" -m "Fixed empty webapps" tomcat01 my-tomcat:1.0
参数说明:
-a:指定作者-m:添加提交信息tomcat01:容器名称或IDmy-tomcat:1.0:新镜像的名称和标签
虽然commit很方便,但在生产环境中不推荐频繁使用。更好的做法是使用Dockerfile构建可复现的镜像。
4.2 使用Dockerfile构建最佳实践
创建一个完整的Tomcat自定义镜像的Dockerfile示例:
dockerfile复制FROM tomcat:9.0.115-jre8-temurin-noble
# 设置工作目录
WORKDIR /usr/local/tomcat
# 复制webapps内容
RUN rm -rf webapps && mv webapps.dist webapps
# 复制自定义配置
COPY conf/server.xml conf/server.xml
COPY conf/web.xml conf/web.xml
# 部署应用
COPY target/myapp.war webapps/
# 设置环境变量
ENV CATALINA_OPTS="-Xms512m -Xmx1024m"
# 暴露端口
EXPOSE 8080
# 启动命令
CMD ["catalina.sh", "run"]
构建命令:
bash复制docker build -t my-tomcat:2.0 .
4.3 多阶段构建优化镜像大小
对于Java应用,可以使用多阶段构建大幅减小最终镜像大小:
dockerfile复制# 第一阶段:构建应用
FROM maven:3.8-openjdk-11 as builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package
# 第二阶段:运行环境
FROM tomcat:9.0-jre11-temurin
COPY --from=builder /app/target/*.war /usr/local/tomcat/webapps/ROOT.war
这样最终镜像只包含运行所需的Tomcat和WAR文件,不包含Maven和源代码,体积可以减小50%以上。
5. 高级部署技巧与故障排查
5.1 容器网络配置详解
Docker提供了多种网络模式,理解它们对部署至关重要:
-
bridge模式(默认):
- 每个容器获取独立IP
- 通过端口映射访问
- 适合单主机部署
-
host模式:
- 容器直接使用宿主机网络
- 无需端口映射
- 性能更好,但安全性较低
-
自定义网络:
bash复制
docker network create mynet docker run -d --network=mynet --name my-nginx nginx docker run -d --network=mynet --name my-tomcat tomcat- 容器间可以通过名称直接通信
- 提供更好的隔离性
5.2 容器数据持久化方案
对于生产环境,必须考虑数据的持久化:
-
Volume(推荐):
bash复制
docker volume create nginx-data docker run -d -v nginx-data:/usr/share/nginx/html nginx -
Bind Mount:
bash复制
docker run -d -v /host/path:/container/path nginx -
tmpfs Mount:
bash复制
docker run -d --tmpfs /app/cache nginx
对于Tomcat,建议持久化以下目录:
/usr/local/tomcat/logs:日志文件/usr/local/tomcat/webapps:应用文件(如果不需要动态部署可以不用)/usr/local/tomcat/conf:配置文件
5.3 常见问题排查指南
问题1:端口冲突或无法访问
- 检查端口是否被占用:
netstat -tuln | grep 8080 - 检查防火墙设置
- 验证容器是否运行:
docker ps - 查看容器日志:
docker logs [容器ID]
问题2:应用部署后不生效
- 检查WAR文件是否复制到正确位置
- 查看Tomcat启动日志:
docker exec [容器ID] cat logs/catalina.out - 确认应用上下文路径是否正确
问题3:性能问题
- 检查资源限制:
docker stats - 调整JVM内存参数
- 考虑使用Nginx作为Tomcat的反向代理,处理静态资源
5.4 监控与日志管理
生产环境部署后,监控是必不可少的:
- 基础监控:
bash复制docker stats [容器ID]
- 日志收集:
bash复制# 查看实时日志
docker logs -f [容器ID]
# 使用日志驱动(如json-file、syslog等)
docker run --log-driver=json-file --log-opt max-size=10m nginx
- 健康检查:
在Dockerfile中添加:
dockerfile复制HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8080/ || exit 1
6. 生产环境部署建议
经过多次实践,我总结了以下生产环境部署的经验:
-
镜像管理:
- 使用明确的版本标签,避免使用latest
- 定期扫描镜像中的安全漏洞
- 使用私有仓库存储企业镜像
-
配置管理:
- 将配置与镜像分离,使用环境变量或配置文件挂载
- 敏感信息使用Docker secret或专门的配置管理工具
-
资源限制:
bash复制docker run -d --memory="1g" --cpus="1.5" nginx- 防止单个容器占用所有资源
- 根据应用需求合理分配
-
部署策略:
- 使用Docker Compose或Kubernetes编排多容器应用
- 实现蓝绿部署或滚动更新,确保零停机
-
备份方案:
- 定期备份重要数据卷
- 将Dockerfile和配置纳入版本控制
对于中小型项目,可以使用Docker Compose来管理Nginx和Tomcat的组合:
yaml复制version: '3.8'
services:
nginx:
image: nginx:1.25
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- tomcat
tomcat:
image: tomcat:9.0
environment:
- JAVA_OPTS=-Xms512m -Xmx1024m
volumes:
- ./app.war:/usr/local/tomcat/webapps/ROOT.war
这个Compose文件定义了两个服务,并建立了它们之间的依赖关系。通过docker-compose up -d即可一键启动整个应用栈。