How to host multiple web applications in Apache Tomcat

Apache Tomcat can host multiple hosts in a single server.

Each host can have multiple applications, accessed via its own “context path”.

Example

http://galaxy.softwareperformance.expert/andromeda/dashboard

galaxy.softwareperformance.expert is the host name/domain name. As part of the request, a browser will send a request header called Host, so that Tomcat knows which host the browser is looking for (e.g. Host: galaxy.softwareperformance.expert). You can also define a catch all host where if the host name is not recognized by Tomcat, Tomcat will pass the request to the default host.

andromeda is the context path

dashboard is the application (or more precisely, one of the controller classes in the application)

You define multiple hosts in server.xml

    <Engine name="Catalina" defaultHost="default">
      <Host name="default" autoDeploy="false" appBase="/system/site/default">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs/default" prefix="access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b %{User-Agent}i" />
      </Host>
      <Host name="one.softwareperformance.expert" autoDeploy="false" appBase="/system/site/one">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs/one" prefix="access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b %{User-Agent}i" />
      </Host>
      <Host name="two.softwareperformance.expert" autoDeploy="false" appBase="/system/site/two">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs/two" prefix="access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b %{User-Agent}i" />
      </Host>
    </Engine>

Inside <Engine /> element you can define a defaultHost, this would be your catch all.
To define your context paths, you do that by creating folders inside your appBase folders. Consider this example, I’ve annotated how you access each application.

/system/site
├── default
│   ├── blue <- http://192.168.1.127/blue/
│   │   ├── index.html
│   │   └── WEB-INF
│   │       └── classes
│   │           └── example
│   │               └── DashboardController.class
│   ├── green <- http://192.168.1.127/green/
│   │   ├── index.html
│   │   └── WEB-INF
│   │       └── classes
│   │           └── example
│   │               └── DashboardController.class
│   └── ROOT <- http://192.168.1.127/
│       ├── index.html
│       └── WEB-INF
│           └── classes
│               └── example
│                   └── DashboardController.class
├── one
│   ├── circle <- http://one.softwareperformance.expert/circle/
│   │   ├── index.html
│   │   └── WEB-INF
│   │       └── classes
│   │           └── example
│   │               └── DashboardController.class
│   ├── ROOT <- http://one.softwareperformance.expert/
│   │   ├── index.html
│   │   └── WEB-INF
│   │       └── classes
│   │           └── example
│   │               └── DashboardController.class
│   └── square <- http://one.softwareperformance.expert/square/
│       ├── index.html
│       └── WEB-INF
│           └── classes
│               └── example
│                   └── DashboardController.class
└── two
    ├── a <- http://two.softwareperformance.expert/a/
    │   ├── index.html
    │   └── WEB-INF
    │       └── classes
    │           └── example
    │               └── DashboardController.class
    ├── b <- http://two.softwareperformance.expert/b/
    │   ├── index.html
    │   └── WEB-INF
    │       └── classes
    │           └── example
    │               └── DashboardController.class
    └── ROOT <- http://two.softwareperformance.expert/
        ├── index.html
        └── WEB-INF
            └── classes
                └── example
                    └── DashboardController.class

Something I’ve always wondered for quite some time is what happens in this case. If I access http://192.168.1.127/blue/, would I be getting the index.html in a or b?

/system/site/default
├── blue
│   ├── index.html <- a
│   └── WEB-INF
│       └── classes
│           └── example
│               └── DashboardController.class
├── green
│   ├── index.html
│   └── WEB-INF
│       └── classes
│           └── example
│               └── DashboardController.class
└── ROOT
    ├── blue
    │   └── index.html <- b
    ├── green
    │   └── index.html
    ├── index.html
    └── WEB-INF
        └── classes
            └── example
                └── DashboardController.class

Here are the content of the index.html files

root@aurora:/system/site# cat default/blue/index.html
Welcome default blue
root@aurora:/system/site# cat default/ROOT/blue/index.html
Welcome blue inside default
Turns out we get a, so a context path takes precendence than a folder

Leave a Reply

Your email address will not be published. Required fields are marked *