当前位置: 首页 > 知识库问答 >
问题:

如何在Tomcat中使用docker卷部署war/jar

胡元忠
2023-03-14

有可能在Tomcat中部署一些java war或jar文件吗?我找了很多教程,我找到的唯一解决方案是将项目war文件复制到/usr/local/tomcat/webapps/中。

我实际上使用了这个解决方案,但我想改进我的文档化。我的主要目标是当我用docker-comush运行我的两个映像(tomcat和db映像中的应用程序)时,我想使用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"

还有那只雄猫的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

当我想在构建新的war时尝试重新启动容器时,发生了这个错误。

共有3个答案

施永宁
2023-03-14

你的问题看起来比看起来简单。首先,是的,你可以做到这一点,这里有一个非常好的生产级示例: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

我在你的例子中看到,你甚至不需要docker文件,你可以用docker compose文件中的图像替换构建,只需装入卷。除非你在docker文件里做额外的事情。

伊俊能
2023-03-14

虽然这并不能准确地回答你的问题,但有一种选择可以考虑,它不要求你有不同的开发配置而不是测试或生产。

只需在本地构建war文件,然后docker cpit:

docker cp D:\myproj\target\app.war My_Tomcat_Container:/usr/local/tomcat/webapps/ROOT.war
谢奕
2023-03-14

你有两个不同的问题:

>

  • 根据您使用的命令,Maven可能会删除并重新创建您的目标目录,这将使已删除的旧目标目录仍然由Docker进程为卷挂载打开。您的旧文件将被删除,新文件将被创建到Docker不知道的新目录中。

    当Maven构建一个新的WAR ZIP文件时,您的servlet运行程序可能会在构建中注意到这个新文件,并尝试打开一个不完整的WAR,这当然会以失败告终。

    我建议您创建一个单独的,至少是半永久的目录,而不是在目标树中,以便由Docker挂载。在您的pom.xml文件中创建一个新的Maven配置文件,并添加一个构建目标,该目标在构建完成后将您的WAR文件复制到该新目录中,并在容器中作为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用户。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>
    

    管理器上下文。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映像。

    我们希望通过使用卷而不是额外的插件来实现这一点。

    ...你可以这样做:

    >

    运行mvn包。

    复制WAR文件,比如用一个脚本来完成整个事情,从构建到部署,到目录C:/示例/战争。我们之所以采取这一步骤,只是因为您可能会运行mvn清洁,这将删除目标目录,如果您直接安装它,Docker可能不会注意到由mvn创建的新目标目录。

    使用docker ps查找您的容器名称。

    再次从部署脚本docker exec$CONTAINER mv /tmp/example/wars/*. war /usr/local/tomcat/webapps/运行该命令,该命令将在Docker容器内的虚拟机内将完整的、未中断的WAR ZIP文件复制到部署目录中。

  •  类似资料:
    • 我已经在archlinux上安装了tomcat,我尝试了tomcat7和Tomcat8。根据包括官方文档在内的多个来源,部署WAR文件就像将其放入webapps文件夹(在我的示例中是/var/lib/tomcat7/webapps)一样容易。WAR文件被分解。但我不知道如何访问我的web应用程序。在localhost:8080上有一个tomcat网页。我还尝试了localhost:8080/nam

    • 我在Eclipse中使用Maven。是否可以构建项目,然后将构建的WAR文件部署到Tomcat服务器? 我使用Windows。我可以构建文件,也可以手动部署在服务器上。但是我想在构建操作后自动部署文件,它不起作用。我是Maven的新手。 我应该在运行配置中设置一些内容吗?我设定了安装价值的目标。 pom。xml 此外,我更改了设置。路径中的xml文件。平方米/设置。xml。 设置。xml

    • 我试图在独立的Tomcat服务器中部署我的Spring Boot应用程序(war),但每次我都得到一个关于Logger的错误。你对这个案子有什么想法吗? 正如您所看到的,我使用的是tomcat 8.0.24、Spring Boot 1.2.5.Release和java.Version1.7。 我的项目非常简单(它作为一个jar工作): 1.主APP: 2.控制器

    • 问题内容: 我已将文件复制到的目录中,并且可以访问。 现在将如何部署它,我的意思是我需要在浏览器中打开它吗?如何访问该应用程序? 问题答案: 你可以从以下位置访问你的应用程序: http://localhost:8080/sample 默认情况下,war文件的部署或重新部署是自动的-复制/覆盖文件后,检查webapps文件夹中是否有解压缩的文件夹z。 如果无法正常打开,请检查日志文件(例如)是否存

    • 我正试图将一个新的war文件部署到我的tomcat服务器上,但我没有看到我的更改得到反映。以下是我的工作流程: 在代码中添加了额外的日志记录 运行以下Ant任务:clean/dist dev/generate war 停止Apache Tomcat服务 删除新生成的。war文件保存到webapps文件夹中 启动ApacheTomcat服务 结果:web应用程序正常启动,但我的新日志功能没有反映在日

    • 5.使用cmd重新启动tomcat。 “信息:部署web应用程序目录C:\apache-tomcat-7.0.77\webapps\MyProject Jun 07,2017 4:50:19 PM org.apache.catalina.startup.hostconfig deployDirectory信息:web应用程序目录C:\apache-tomcat-7.0.77\webapps\MyP