Sometimes the right shape for an environment is to serve several distinct domains from a single set of compute resources — multiple themed sites for marketing campaigns, sibling apps that share infrastructure, a multi-tenant deployment of the same codebase. The PaaS supports this with a public IP plus the application server’s native virtual-host configuration.
The example below uses Tomcat because the configuration is concrete and clear; the same pattern applies to GlassFish, Jetty, NGINX, Apache HTTPD, and Node.js applications that use a framework-level host router.
Why one environment, multiple domains
- Resource efficiency. Two domains do not need two database tiers, two load balancers, two sets of scaling rules.
- Operational simplicity. One environment, one deployment pipeline, one monitoring footprint.
- Differentiated marketing or UX. Different domains routed to different document roots within the same application server let you A/B-test branding, segment user populations, or stage content per audience without duplicating infrastructure.
Prerequisites
- An environment with a public IPv4 attached to the application server (or to the load balancer in front of it).
- DNS A records at your registrar pointing each domain at that public IP.
- Administrative access to each domain.
Multi-domain Tomcat — step by step
-
Create the environment. In the topology wizard, pick Tomcat, enable Public IPv4 for the Tomcat node, name the environment, and create.
-
Find the public IP. In the dashboard, expand the Tomcat node — the public IP is in the drop-down list.
-
Point your domains at the public IP. At your registrar, add an A record per domain (
firstdomain.com → 198.51.100.10,seconddomain.com → 198.51.100.10, etc.). -
Deploy your apps. Upload your WAR files to the Deployment Manager and deploy each one to a separate context. The exact context path matters because the virtual-host config below references the on-disk location.
-
Configure virtual hosts in
server.xml. Click Config on the Tomcat node, navigate to theserverdirectory, openserver.xml, and add a<Host>block per domain inside the<Engine>element:
<Host name="firstdomain.com" appBase="webapps/firstdomain">
<Alias>firstdomain.com</Alias>
<Context path="" docBase="."/>
</Host>
<Host name="seconddomain.com" appBase="webapps/seconddomain">
<Alias>seconddomain.com</Alias>
<Context path="" docBase="."/>
</Host>
<Host name="thirddomain.com" appBase="webapps/thirddomain">
<Alias>thirddomain.com</Alias>
<Context path="" docBase="."/>
</Host>
The key fields:
name— the domain Tomcat will match against the incomingHostheader.appBase— the directory (under$CATALINA_HOME, typicallywebapps/) containing the application for that domain.<Alias>— additional hostnames that should route to the sameappBase(e.g.www.firstdomain.com).<Context path="" docBase="."/>— root context of the application is.relative toappBase.
- Save and restart Tomcat. Use the dashboard’s restart action so the new
server.xmlis picked up.
Each domain now resolves to its own document root on the same Tomcat instance.
Redeploy gotcha
If you redeploy an application to a Tomcat node whose server.xml already has custom <Host> blocks, the deployment may fail or get rewritten because the deploy step tries to manage webapps/ itself.
The workaround is straightforward:
- Comment out the relevant
<Host>block inserver.xml. - Redeploy.
- Uncomment the block.
- Restart Tomcat.
For environments where redeploys are frequent, consider externalizing the host configuration into conf/Catalina/<hostname>/ files instead of editing server.xml directly — Tomcat treats each per-host file as authoritative for that host and the deploy step leaves them alone.
Other application servers
The same general shape works elsewhere:
- GlassFish / Payara — virtual servers in the admin console, mapped to deployed applications.
- NGINX —
server { server_name ...; root ...; }blocks, one per domain. - Apache HTTPD —
<VirtualHost>blocks withServerNameandDocumentRoot. - Node.js — a framework-level router (Express, Fastify) keyed off
req.hostname.