Docker部署Tomcat中WAR文件及JS文件夹自动删除问题排查
问题描述
部署环境:
- Docker版本1.13.1,宿主机内核3.10.0-862.el7.x86_64
- Tomcat 9.0 + Java 1.8
- 将包含1个WAR文件、2个JavaScript文件夹、1个manager-gui文件夹的外部目录挂载到Tomcat容器内
问题现象:挂载目录中的WAR文件和JavaScript文件夹会被自动删除,但manager-gui文件夹留存。已尝试修改系统权限、重建Tomcat容器,问题仍存在。
相关日志:
->security.proto13-Dec-2022 10:10:16.849 INFO [http-nio-8080-exec-124] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/admin-manager] col = PLAINTEXT send.buffer.bytes = 131072 ->13-Dec-2022 10:10:17.653 INFO [http-nio-8080-exec-208] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/dashboard] ->13-Dec-2022 10:10:19.848 INFO [http-nio-8080-exec-185] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/linedashboard] ->13-Dec-2022 10:10:21.182 WARNING [http-nio-8080-exec-152] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [moep] registered the JDBC driver [com.mysql.cj.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. ->13-Dec-2022 10:10:21.182 WARNING [http-nio-8080-exec-152] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [moep] registered the JDBC driver [com.microsoft.sqlserver.jdbc.SQLServerDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
原因分析
- Tomcat自动部署机制触发清理:Tomcat的HostConfig组件会监控webapps目录变化,日志中可见多个应用上下文被undeploy,此时Tomcat会自动清理对应WAR文件及关联的应用资源(包括你的JS文件夹);而manager-gui是Tomcat自带管理应用,默认不受自动清理规则影响。
- 权限映射或SELinux限制:即使修改过权限,宿主机与容器的用户权限可能未完全匹配(Tomcat容器内通常用tomcat用户运行),再加上CentOS 7默认开启的SELinux,可能导致Tomcat在处理部署时触发异常清理逻辑。
- 旧版Docker挂载缺陷:Docker 1.13.1版本较旧,绑定挂载(bind mount)存在目录同步问题,容器内的删除操作会直接同步到宿主机;而manager-gui不在自动监控的部署资源范围内,因此未被删除。
解决办法
调整Tomcat自动部署规则
- 修改
conf/server.xml的<Host>标签,关闭自动部署:
之后手动复制资源到容器内,避免Tomcat自动清理。<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="false" deployOnStartup="false"> - 将需要保留的JS文件夹迁移至Tomcat非部署目录(如
conf/static),修改应用配置引用该目录下的资源,脱离自动监控范围。
修复权限与SELinux问题
- 匹配容器内外用户权限:先查看容器内tomcat用户UID:
假设UID为1000,在宿主机设置挂载目录权限:docker exec -it <容器ID/名称> id tomcatchown -R 1000:1000 /宿主机挂载路径 chmod -R 755 /宿主机挂载路径 - 临时关闭SELinux验证:
setenforce 0,若问题解决,可修改/etc/selinux/config将SELINUX设为disabled永久关闭。
优化Docker挂载方式
- 升级Docker至稳定版(如20.10.x),修复旧版本绑定挂载的同步缺陷。
- 改用Docker数据卷替代绑定挂载:
# 创建数据卷 docker volume create tomcat-webapps # 启动容器时挂载数据卷 docker run -d -v tomcat-webapps:/usr/local/tomcat/webapps tomcat:9.0-jdk8 # 复制资源到容器内 docker cp /宿主机WAR文件 <容器ID/名称>:/usr/local/tomcat/webapps/
内容的提问来源于stack exchange,提问作者Rajesh rai
相关产品推荐
相关产品推荐

