如何在Docker容器中热部署Java EE应用程序

10
我正在寻找将Java EE应用程序热部署到Docker容器中的可能性。最有趣的内容是通过“卷”在主机和容器之间共享tomcat目录的可能性。但这还不是热部署。
参考:https://groups.google.com/forum/#!topic/docker-user/b_4NRn9sLBQ 如何实现热部署?有什么建议吗?

为什么要使用AS进行部署?嵌入式AS的可运行jar包呢? - Opal
在我工作的公司中,有一些遗留系统需要超过2分钟才能构建完成。当我们使用热部署时,我们可以在几秒钟内看到更改。考虑到这一点,使用热部署工作效率更高。 - wrenzi
对我来说,这种分享方式违背了Docker的理念。 - Jacek Cz
2个回答

5

我知道这个问题有点旧,但我想分享一下如何在Docker中使用tomee服务器开发Java EE应用的知识。

准备Docker镜像

首先要做的是启用日志记录。我使用官方基础镜像,并将日志重定向到标准输出以便在控制台上查看:

# you can change the base image of course
FROM tomee:8-jre-1.7.5-jaxrs
RUN ln -s /dev/stdout /usr/local/tomee/logs/catalina.out 
RUN echo '<?xml version="1.0" encoding="utf-8"?><tomcat-users><role rolename="tomee-admin"/><user username="tomee" password="tomee" roles="tomee-admin,manager-gui,manager-script"/></tomcat-users>' > /usr/local/tomee/conf/tomcat-users.xml

日志添加可能看起来不是很重要,但实际上它非常重要。启用此功能后,您可以立即查看部署的成功或失败情况。

丑陋的xml片段实际上非常重要。它使得名为tomee的用户拥有部署应用程序的所有重要权限。

您可以使用普通的Docker工具构建镜像:

docker build -t tomee-dev .

准备开发环境

我使用标准的Maven目录结构,以下是一个示例:

pom.xml
src
 |
 - main
    |
    - java
    |   |
    |   - boundary
    |        |
    |        - TestResource.java
    - webapp
        |
        - WEB-INF
            |
            - web.xml

这些文件的内容可以在本答案底部找到。
像这样启动容器:
docker run -it --rm -p 8080:8080 tomee-dev

最后一步是我们的Maven配置。你可以使用tomee Maven插件进行重新部署。
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <url>http://localhost:8080/manager/text</url>
                <username>tomee</username>
                <password>tomee</password>                    
                <path>/${project.artifactId}</path>
            </configuration>
        </plugin>
    </plugins>
</build>

现在你可以使用mvn clean tomcat7:deploymvn clean tomcat7:redeploy命令来部署/重新部署你的应用程序。

附录

以下是我在示例中使用的源文件和配置文件的内容:

src/main/java/boundary/TestResource.java

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("/")
public class TestResource {

    @GET
    @Path("test")
    public Response test1() {
        return Response.ok("this is a test").build();
    }
}

src/main/java/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <module-name>hot-deploy</module-name>

    <servlet>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>javax.ws.rs.core.Application</servlet-name>
        <url-pattern>/resources/*</url-pattern>
    </servlet-mapping>
</web-app>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <artifactId>hot-reload</artifactId>
    <groupId>org.test.stackoverflow.answers</groupId>
    <version>1.0.0-snapshot</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <tomee-plugin.pwd>tomee</tomee-plugin.pwd>
        <tomee-plugin.user>tomee</tomee-plugin.user>

    </properties>



    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <scope>provided</scope>
            <version>7.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <url>http://localhost:8080/manager/text</url>
                    <username>tomee</username>
                    <password>tomee</password>                    
                    <path>/${project.artifactId}</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

0
如果您将主机的卷挂载到几个容器上,只读,请确保Tomcat不会“爆炸”WAR文件,至少不要到同一个文件夹,那么我认为您已经实现了热部署,至少在Tomcat支持的水平上。在主机文件夹中替换.war文件应该会触发重新部署。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接