Issue
The task is to build and deploy a simple Hello World-Web-Application with Java and Docker. It should print out a Hello World! when typing in the IP-adress and the port of the server in browser. I already made it working on localhost and on the server with following codes:
On localhost I am creating a new folder in the "webapps" directory called "ROOT". I am exchanging it with the original "ROOT"-directory from Tomcat. On localhost I have only the "WEB-INF" folder in it and in the "WEB-INF" folder there are my "web.xml" file and the "classes" folder. In "classes" folder there are the "HelloWorld.java" and "HelloWorld.class" file.
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!");
}
}
When I type localhost:8080 in browser after I started up tomcat in cmd, everything works out fine. I'm getting my Hello World!.
Now when I create a .war file of my "ROOT" folder on my local computer and then put the whole "ROOT" directory from my local computer on the server with FileZilla(the ROOT.war file is at the same place as the "WEB-INF" directory in the "ROOT" directory), I create a docker image which looks like this:
From tomcat:9.0
Run rm -rf /usr/local/tomcat/webapps/ROOT
ADD /ROOT /usr/local/tomcat/webapps/
CMD ["catalina.sh","run"]
I'm basically just removing the original "ROOT"-folder from tomcat in the image and replace it with my own where the ROOT.war file is in. Then I build the image and run it with:
docker run -p 0.0.0.0:8888:8080
And it works out completely fine , everything works when I type in the IP-adress of the server in my Browser, Im getting the Hello World!.
But now the problem is that I dont want always to create the .war file on my local computer so I want to create it right when the docker image is build. So I removed the "ROOT.war" file from the "ROOT"-directory on the server and made a new Dockerfile:
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"]
OR
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"]
In both options that I tried the image and the .war file were build and run without issues but suddenly when I type in the IP-adress of the server in my browser, I'm just getting an error 404 message and a description:
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.
I dont know what is happening. The only difference is basically that when it worked I created the .war file locally and put it on the server in the "ROOT"-folder manually and added the whole "ROOT" folder in the "webapps" folder in the docker image. And with the second attempt I just created exactly the same "ROOT.war" file in the same folder but in the docker image. Why is this not working?
Solution
Your Docker command is wrong in multiple ways. When you do a:
CMD ["cd /usr/local/tomcat/webapps/ROOT","jar -cvf ROOT.war ."]
The CMD command is really CMD ["executable, "param1", "param2"]
The cd
command will ignore the remaining arguments so while it does do a cd
it doesn't do anything else.
Additionally, you're using the c
flag in your jar command. This is to create, not extract. Use the x
parameter to extract.
But Tomcat does not need you extract the .war
file - it will do that at startup. So you really only need:
COPY /ROOT /usr/local/tomcat/webapps/ROOT
CMD ["/usr/local/tomcat/bin/startup.sh"]
Answered By - stdunbar
Answer Checked By - Clifford M. (JavaFixing Volunteer)