[英]How to use docker volume to deploy war / jar in Tomcat
是否可以在Tomcat中部署一些java war或jar文件? 我找了很多教程,我找到的唯一解决方案是将项目war文件复制到/usr/local/tomcat/webapps/
。
我实际上使用了这个解决方案,但我想改进我的dockerisation。 我的主要目标是当我使用docker-compose运行我的2个图像(tomcat和db image中的应用程序)时,我想在tomcat中使用目标文件夹的本地war文件,当我在代码更改后再次构建war时,将在不停止容器,移除和重建的情况下进行反映。 你可以帮忙吗? 我的尝试失败了。 我希望它仅用于开发目的。
这是我的docker-compose.yml
version: '3'
services:
tomcat-service:
build:
context: ../
dockerfile: docker/app/Dockerfile
volumes:
- D:\myproj\target\app.war:/usr/local/tomcat/webapps/ROOT.war
ports:
- "8080:8080"
depends_on:
- "db-service"
db-service:
build: ./database
ports:
- "5433:5432"
和那个tomcat的Dockerfile
FROM tomcat:8.0-jre8
RUN rm -rvf /usr/local/tomcat/webapps/ROOT
COPY ./docker/app/context.xml /usr/local/tomcat/conf/
# with following copy command it works, but when I rebuild war file, I need stop docker-compose and build and run it again .. I want use volume instead of copy war
#COPY ./pnp-web/target/pnp.war /usr/local/tomcat/webapps/ROOT.war
EXPOSE 8080
CMD ["catalina.sh", "run"]
使用上面的配置应用启动,但是当我运行mvn clean package
应用程序不再被加载
编辑
我检查了tomcat容器的日志,我发现了这个错误:
tomcat-cont | 10-Jul-2018 08:20:36.754 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /usr/local/tomcat/webapps/ROOT.war
tomcat-cont | 10-Jul-2018 08:20:36.858 SEVERE [localhost-startStop-1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
tomcat-cont | org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
tomcat-cont | at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
tomcat-cont | at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:755)
tomcat-cont | at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:731)
tomcat-cont | at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
tomcat-cont | at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:973)
tomcat-cont | at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1850)
tomcat-cont | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
tomcat-cont | at java.util.concurrent.FutureTask.run(FutureTask.java:266)
tomcat-cont | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
tomcat-cont | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
tomcat-cont | at java.lang.Thread.run(Thread.java:748)
tomcat-cont | Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.webresources.StandardRoot@51f50cb1]
tomcat-cont | at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:162)
tomcat-cont | at org.apache.catalina.core.StandardContext.resourcesStart(StandardContext.java:5016)
tomcat-cont | at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5149)
tomcat-cont | at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
tomcat-cont | ... 10 more
tomcat-cont | Caused by: org.apache.catalina.LifecycleException: Failed to initialize component [org.apache.catalina.webresources.JarResourceSet@20e48a4a]
tomcat-cont | at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
tomcat-cont | at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:135)
tomcat-cont | at org.apache.catalina.webresources.StandardRoot.startInternal(StandardRoot.java:722)
tomcat-cont | at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
tomcat-cont | ... 13 more
tomcat-cont | Caused by: java.lang.IllegalArgumentException: java.util.zip.ZipException: error in opening zip file
tomcat-cont | at org.apache.catalina.webresources.AbstractSingleArchiveResourceSet.initInternal(AbstractSingleArchiveResourceSet.java:142)
tomcat-cont | at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)
tomcat-cont | ... 16 more
tomcat-cont | Caused by: java.util.zip.ZipException: error in opening zip file
tomcat-cont | at java.util.zip.ZipFile.open(Native Method)
tomcat-cont | at java.util.zip.ZipFile.<init>(ZipFile.java:225)
tomcat-cont | at java.util.zip.ZipFile.<init>(ZipFile.java:155)
tomcat-cont | at java.util.jar.JarFile.<init>(JarFile.java:166)
tomcat-cont | at java.util.jar.JarFile.<init>(JarFile.java:130)
tomcat-cont | at org.apache.tomcat.util.compat.JreCompat.jarFileNewInstance(JreCompat.java:170)
tomcat-cont | at org.apache.tomcat.util.compat.JreCompat.jarFileNewInstance(JreCompat.java:155)
tomcat-cont | at org.apache.catalina.webresources.AbstractSingleArchiveResourceSet.initInternal(AbstractSingleArchiveResourceSet.java:139)
tomcat-cont | ... 17 more
tomcat-cont |
tomcat-cont | 10-Jul-2018 08:20:36.859 SEVERE [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Error deploying web application archive /usr/local/tomcat/webapps/ROOT.war
tomcat-cont | java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].Stand
ardContext[]]
tomcat-cont | at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
tomcat-cont | at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:731)
tomcat-cont | at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
tomcat-cont | at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:973)
tomcat-cont | at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1850)
tomcat-cont | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
tomcat-cont | at java.util.concurrent.FutureTask.run(FutureTask.java:266)
tomcat-cont | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
tomcat-cont | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
tomcat-cont | at java.lang.Thread.run(Thread.java:748)
tomcat-cont |
tomcat-cont | 10-Jul-2018 08:20:36.860 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive /usr/local/tomcat/webapps/ROOT.war has finish
ed in 105 ms
当我想在新战争建立时尝试重启容器时发生了这个错误。
你有两个不同的问题:
根据您使用的命令,Maven可能会删除并重新创建target
目录,这将使Docker进程仍然为卷装入打开旧的已删除target
目录。 您的旧文件将被删除,新文件将创建到Docker不知道的新目录中。
当Maven构建一个新的WAR ZIP文件时,你的servlet运行器可能会注意到中间构建的新文件,并尝试打开一个半生不熟的WAR,这当然会以失败告终。
我建议您创建一个单独的,至少是半永久性的目录,而不是在target
树中,以便由Docker挂载。 在pom.xml
文件中创建一个新的Maven配置文件,并添加一个构建目标,在构建完成后将其复制到新目录中,该目录将作为Tomcat的webapps
挂载到容器中。
编辑:这是一个解决方案,它不依赖于Docker使用的虚拟化系统在任何特定平台上实现卷文件传输的特定方式。
https://git.mikael.io/mikaelhg/docker-tomcat-war-deploy-poc
pom.xml
片段:
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.6.8</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
<type>remote</type>
</container>
<configuration>
<type>runtime</type>
<properties>
<cargo.protocol>http</cargo.protocol>
<cargo.hostname>localhost</cargo.hostname>
<cargo.servlet.port>8080</cargo.servlet.port>
<cargo.remote.username>admin</cargo.remote.username>
<cargo.remote.password>admin</cargo.remote.password>
</properties>
</configuration>
<deployer>
<type>remote</type>
</deployer>
<deployables>
<deployable>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<type>${project.packaging}</type>
<properties>
<context>/app</context>
</properties>
</deployable>
</deployables>
</configuration>
</plugin>
docker-compose.yml
片段:
tomcat:
image: tomcat:8
volumes:
- ./tomcat-users.xml:/usr/local/tomcat/conf/tomcat-users.xml
- ./manager-context.xml:/usr/local/tomcat/webapps/manager/META-INF/context.xml
ports:
- "8080:8080"
depends_on:
- db
tomcat-users.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user username="admin" password="admin" roles="manager-gui,manager-script"/>
</tomcat-users>
manager-context.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true">
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
然后:
mvn package
mvn cargo:redeploy
编辑2:作为回应“......如果没有额外的插件可以做到这一点吗?” 在评论中:
是。 如果你:
在主机上运行Windows,在虚拟机中运行Tomcat Docker镜像。
希望通过使用卷来实现这一点,而不需要额外的插件。
......你可以这样做:
例如,将C:/example/wars
挂载到Docker容器' /tmp/example/wars
。
运行mvn package
。
复制WAR文件,比如使用完成整个操作的脚本,从构建到部署,再复制到目录C:/example/wars
。 我们只采取这一步,因为您可能运行mvn clean
将删除target
目录,如果您直接挂载它,Docker可能不会注意到mvn
创建的新target
目录。
使用docker ps
查找容器名称。
再次从您的部署脚本, docker exec $CONTAINER mv /tmp/example/wars/*.war /usr/local/tomcat/webapps/
运行该命令,它将在Docker容器内复制到虚拟机内部,完成,将未破坏的WAR ZIP文件放入部署目录。
你的问题似乎比看上去简单。 首先,是的,你可以做到这一点,这是一个非常好的生产等级示例: https : //hub.docker.com/r/esystemstech/liferay
关于您的docker文件,除了将文件隐藏在图层下之外,此行不会为您做任何事情:
RUN rm -rvf /usr/local/tomcat/webapps/ROOT
这意味着这甚至不能节省空间。 现在,考虑将文件夹作为卷而不是文件。 您也可以将上下文保留在文件中。 最后只是检查时间是否正确,我的意思是,如果你在打包操作后重新启动。 我这样说是因为:
Caused by: java.util.zip.ZipException: error in opening zip file
对于我在示例中看到的内容,您甚至不需要Dockerfile,可以使用docker compose文件中的image
替换build
,然后安装卷。 除非你在docker文件中做了额外的事情。
虽然这不能完全回答您的问题,但有一种替代方案可以考虑,不需要您具有与测试或生产不同的开发配置。
只需在本地构建你的war文件然后docker cp
:
docker cp D:\myproj\target\app.war My_Tomcat_Container:/usr/local/tomcat/webapps/ROOT.war
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.