为什么在 docker 图像中创建的 .war 文件在浏览器中不起作用? (Java-Servlets,Tomcat,Docker)

Why a .war file created in docker image is not working in browser? (Java-Servlets, Tomcat, Docker)

任务是使用 Java 和 Docker 构建和部署一个简单的 Hello World-Web-Application。它应该打印出一个 Hello World!在浏览器中输入 IP 地址和服务器端口时。我已经使用以下代码使其在本地主机和服务器上运行:

在本地主机上,我正在“webapps”目录中创建一个名为“ROOT”的新文件夹。我将它与 Tomcat 中的原始“ROOT”目录交换。在本地主机上,我只有“WEB-INF”文件夹,在“WEB-INF”文件夹中有我的“web.xml”文件和“类”文件夹。在“类”文件夹中有“HelloWorld.java”和“HelloWorld.class”文件。

apache-tomcat-9.0.36/webapps/ROOT/WEB-INF/web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <servlet>
        <servlet-name>SimpleTryOutApplication</servlet-name>
        <servlet-class>HelloWorld</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>SimpleTryOutApplication</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

apache-tomcat-9.0.36/webapps/ROOT/WEB-INF/classes/HelloWorld.java:

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {

        PrintWriter out = response.getWriter();

        out.println("Hello World!");

    }

}

当我在 cmd 中启动 tomcat 后在浏览器中键入 localhost:8080 时,一切正常。我得到了我的 Hello World!

现在,当我在本地计算机上为我的“ROOT”文件夹创建一个 .war 文件,然后使用 FileZilla(ROOT.war 文件与“ROOT”目录中的“WEB-INF”目录位于同一位置),我创建了一个 docker 图像,如下所示:

From tomcat:9.0

Run rm -rf /usr/local/tomcat/webapps/ROOT

ADD /ROOT /usr/local/tomcat/webapps/

CMD ["catalina.sh","run"]

我基本上只是从图像中的 tomcat 中删除原始的“ROOT”文件夹,并将其替换为我自己的 ROOT.war 文件所在的文件夹。然后我构建图像并运行 它与:

docker run -p 0.0.0.0:8888:8080

一切正常,当我在浏览器中输入服务器的 IP 地址时,一切正常,我收到了 Hello World!

但现在的问题是我不想总是在我的本地计算机上创建 .war 文件,所以我想在构建 docker 映像时立即创建它。所以我从服务器上的“ROOT”目录中删除了“ROOT.war”文件并创建了一个新的Docker文件:

From tomcat:9.0

Run rm -rf /usr/local/tomcat/webapps/ROOT

ADD /ROOT /usr/local/tomcat/webapps/

WORKDIR /usr/local/tomcat/webapps/ROOT

Run jar -cvf ROOT.war .

CMD ["catalina.sh","run"]

From tomcat:9.0

Run rm -rf /usr/local/tomcat/webapps/ROOT

ADD /ROOT /usr/local/tomcat/webapps

CMD ["cd /usr/local/tomcat/webapps/ROOT","jar -cvf ROOT.war ."]

CMD ["catalina.sh","run"]

在我尝试过的两个选项中,图像和 .war 文件都已构建并且 运行 没有问题,但是突然当我在浏览器中输入服务器的 IP 地址时,我我刚收到错误 404 消息和描述:

404
Message: The requested resource [/] is not available
Description: The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.

我不知道发生了什么。唯一的区别基本上是,当它工作时,我在本地创建了 .war 文件并手动将其放在服务器上的“ROOT”文件夹中,并将整个“ROOT”文件夹添加到“webapps”文件夹中docker 图片。第二次尝试时,我在同一文件夹中创建了完全相同的“ROOT.war”文件,但在 docker 图像中。为什么这不起作用?

您的 Docker 命令在多个方面都是错误的。当您执行以下操作时:

CMD ["cd /usr/local/tomcat/webapps/ROOT","jar -cvf ROOT.war ."]

CMD命令真的是CMD ["executable, "param1", "param2"]

cd 命令将忽略剩余的参数,因此当它执行 cd 时它不会执行任何其他操作。

此外,您在 jar 命令中使用了 c 标志。这是创建,而不是提取。使用x参数提取。

但是 Tomcat 不需要您提取 .war 文件 - 它会在启动时执行此操作。所以你真的只需要:

COPY /ROOT /usr/local/tomcat/webapps/ROOT

CMD ["/usr/local/tomcat/bin/startup.sh"]