How to set up Tomcat virtual hosts

Wed, 04/26/2017 - 10:50

In the previous post we showed how to set up virtual hosts on Apache 2 server to host a PHP application. In this post we are going to be focused on Apache Tomcat Server for hosting JAVA web applications. First you have to download Tomcat from https://tomcat.apache.org/. I have downloaded Apache Tomcat 9 to my Ubuntu machine within /home/ara/java/apache-tomcat-9.0.0.M9  directory and it is completely owned by me - i.e. ara.

Let's say we want to access our Java web application in our browser by typing www.domain.local  and not something like localhost:8080/myappname. Like in the previous post regardless of what server we use we have to first map our domain name to the local IP address. So we have to edit the /etc/hosts file. I will open it in sublime text editor. 

$ sudo subl /etc/hosts

and add the mentioned domain ~ ip address mapping

127.0.0.1       www.domain.local

Save the changes and close the file.

In order to show some dummy content to the visitor of our web page let's create a very simple project and deploy it to our Tomcat server. We start by creating the directory structure right on our ~/Desktop 

$ mkdir -p ~/Desktop/WebApp/WEB-INF

$ touch ~/Desktop/WebApp/WEB-INF/web.xml ~/Desktop/WebApp/index.html

The newly created WebApp folder content on our Desktop will look like this

WebApp
├── index.html
└── WEB-INF
    └── web.xml

web.xml is going to tell the Tomcat that index.html is our welcome file, meaning that it is going to be invoked automatically by the server, if we don't specify any file name. To do so let's open the web.xml file in our favorite text editor.

$ subl ~/Desktop/WebApp/WEB-INF/web.xml

and type the following configuration tags into it

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

Save the file and close it.

For the welcome text in the index.html welcome file, we simply run the next command in our terminal.

$ echo "<h1>Welcome to www.domain.local</h1>" > ~/Desktop/WebApp/index.html

Ok, now we can make the war file for the deployment

$ cd ~/Desktop/WebApp/
$ jar -cvf deployment.war *

the ~/Desktop/WebApp/deployment.war file has been created and it is ready to be deployed, but before deployment let's make sure that no other servers are running. The Apache 2 server from the previous post for example. To stop it we run in terminal

$ sudo service apache2 stop

Let's do our deployment now.

$ mv deployment.war ~/java/apache-tomcat-9.0.0.M9/webapps/deployment.war

By the time we start the server we will have a new deployment/ directory created in  ~/java/apache-tomcat-9.0.0.M9/webapps/. In order to start the server we head to bin/ directory

$ cd ~/java/apache-tomcat-9.0.0.M9/bin/

and run the startup.sh script file

$ ./startup.sh 
Using CATALINA_BASE:   /home/ara/java/apache-tomcat-9.0.0.M9
Using CATALINA_HOME:   /home/ara/java/apache-tomcat-9.0.0.M9
Using CATALINA_TMPDIR: /home/ara/java/apache-tomcat-9.0.0.M9/temp
Using JRE_HOME:        /home/ara/java/jdk1.8.0_101
Using CLASSPATH:       /home/ara/java/apache-tomcat-9.0.0.M9/bin/bootstrap.jar:/home/ara/java/apache-tomcat-9.0.0.M9/bin/tomcat-juli.jar
Tomcat started.

It is quite funny and ironic, because so far we have not configured any virtual host on our tomcat server. Instead, we are ready to access our deployment in the browser by typing http://localhost:8080/deployment/, which is quite ugly in my opinion and is the main reason I want to set up the virtual host to access my page on www.domain.local. The Tomcat virtual hosts are configured inside ~/java/apache-tomcat-9.0.0.M9/conf/server.xml file. By default we have a single "Catalina" service defined for all the web applications deployed on our server. This service implements a HTTP/1.1 protocol connector listening for connection on port 8080 and that is not actually what we want. We want to use the port 80, because it is the default well-known http port and we do not want to specify the port every time we type www.domain.local:8080. For that very reason we define a new service called "Catalina80" right below the existing one.

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>


  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>


  <Service name="Catalina80">
    <Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="www.domain.local"  appBase="webapps" unpackWARs="true" autoDeploy="true">
        <Alias>domain.local</Alias>

        <Context path="" docBase="/home/ara/java/apache-tomcat-9.0.0.M9/webapps/deployment"
           debug="0" reloadable="true"/>

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>

</Server>

Save the file and close it. After what we have to restart the server.

$ cd ~/java/apache-tomcat-9.0.0.M9/bin/

We have already run the startup.sh script to start the server and now tomcat is running. We can stop it with the help of another script

$ ./shutdown.sh

and then start it again by

$ ./startup.sh 

We are done! Go to your browser and type www.domain.local.

Tags