How to mask a tomcat app behind an apache subdomain? - apache

I have two separate servers: an Apache public server and an internal Tomcat one. I would like our users to be able to use our Tomcat apps without exposing the details of our implementation (actual port, server name, context) through the public Apache server like this:
http://credits.publicdomain.com/servlet
instead of
http://tomcat.internaldomain.com:8082/CreditsApp/servlet
How can I configure my Apache server to mask requests to our Tomcat apps this way? Is using Apache modules such as mod_rewrite or mod_proxy the most straightforward approach?
I have tried this configuration for a VirtualHost in Apache, which works for the first servlet. However it seems to disable Tomcat to keep the session from the first servlet to any other servlet you go afterwards:
ServerName credits.publicdomain.com
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://tomcat.internaldomain.com:8082/CreditsApp/
ProxyPassReverse / http://tomcat.internaldomain.com:8082/CreditsApp/
Am I missing some additional configuration in my Tomcat server in order to work without the context between servlets?

The best and most efficient way to do this is using mod_jk: http://tomcat.apache.org/connectors-doc/
I've used this in several projects and found it to be extremely easy to use, effective, flexible, and performant. It's also the de facto official solution to stacking Tomcat behind Apache.

mod_jk is what you need to bridge Tomcat to Apache, so you can focus on your app
and Apache, as the front-end, can deal with https and authentication and such. It will forward certain URLs to 'workers' in Tomcat. So you need to tell Apache to load the mod_jk, you need to configure worker.properties, Apache would need to know which worker does what, and you need to define a Service in Tomcat.
These directives in httpd.conf configure mod_jk:
JKWorkersFile conf/workers.properties
JKLogFile /var/log/tomcat/mod_jk.log
JKLogLevel info
The JKWorkersFile in /etc/httpd/conf/workers.properties basically defines sockets
workers.tomcat_home=/var/tomcat4
workers.java_home=/usr/java/jdk
ps=/
worker.list=worker1,worker2
worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker2.port=8010
worker.worker2.host=localhost
worker.worker2.type=ajp13
This snippet for httpd.conf would delegate everything (i.e. /* ) to worker1:
<VirtualHost 192.0.34.72>
ServerAdmin webmaster# example.com
DocumentRoot /www/www.example.com/webapps/ROOT
ServerName www.example.com
ErrorLog logs/public_errors
LogLevel debug
CustomLog logs/public_access combined
JkMount /* worker1
<Directory "/www/www. example.com/webapps/ROOT">
Options Indexes FollowSymLinks Indexes
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<Location "/WEB-INF/">
AllowOverride None
deny from all
</Location>
<Location "/META-INF/">
AllowOverride None
deny from all
</Location>
</VirtualHost>
And Tomcat would have this service:
<service name="public">
<connector classname="org.apache.coyote.tomcat4.CoyoteConnector" port="8009" minprocessors="5" maxprocessors="75" enablelookups="true" redirectport="8443" acceptcount="10" debug="0" connectiontimeout="0" useurivalidationhack="false" protocolhandlerclassname="org.apache.jk.server.JkCoyoteHandler" />
<engine name="Standalone" defaulthost="localhost" debug="0">
<logger classname="org.apache.catalina.logger.FileLogger" prefix="catalina_log." suffix=".txt" timestamp="true" /> <realm classname="org.apache.catalina.realm.UserDatabaseRealm" debug="0" resourcename="UserDatabase" /> 
<host name="localhost" debug="0" appbase="/www/www.example.com/webapps" unpackwars="true" autodeploy="true">
<logger classname="org.apache.catalina.logger.FileLogger" directory="logs" prefix="localhost_log." suffix=".txt" timestamp="true" />
</host>
</engine>
</service>
The above examples are from my notes, check update documentation at:
http://tomcat.apache.org/connectors-doc/generic_howto/workers.html
http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html

Related

Apache and Tomcat 8 configure proxy

I have a web application running in Tomcat 8. I can access this application by opening http://subdomain.domain.com:8080/MYAPP.
Now I want to only enter http://subdomain.domain.com to open this application.
How do I have to configure my Apache 2 or Tomcat 8 to achieve this?
See my answer there for more details.
https://stackoverflow.com/a/26305876/1935128
But basically, you need mod_proxy and maybe mod_proxy_connect enabled on apache with a proper virtualhost configuration on apache side. And on Tomcat's side it may work without any modification but you should add proxyName="subdomain.domain.com, proxyPort="80" and scheme="http"
Tomcat connector :
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"
<!-- This is the important part -->
proxyName="subdomain.domain.com" proxyPort="80"/>
Apache virtualhost:
<VirtualHost subdomain.mydomain.com:80>
ServerName http://subdomain.mydomain.com
# I think these two are optional, depending on the app your run on Tomcat
#ProxyRequests Off
#ProxyPreserveHost On
ProxyPass / http://your.tomcat.server:8080/MYAPP/
ProxyPassReverse / http://your.tomcat.server:8080/MYAPP/
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
</VirtualHost>

Sticky session not working with multiple apache vhosts and multiple JBoss 7.2 server-groups

Having a specific cluster architecture with the following details:
Load balancer (10.10.0.1) using Apache's mod_cluster 1.2.0 without advertising using multicast
2 JBoss AS 7.2 servers (jboss-instance-1, jboss-instance-1) in domain mode (host and slave), i'm using proxy-list instead of multicast
In domain.xml i have the following settings (only important snippets):
...
<subsystem xmlns="urn:jboss:domain:modcluster:1.1">
<mod-cluster-config advertise-socket="modcluster" connector="ajp" balancer="${mycluster.modcluster.balancer:DefaultBalancer}" proxy-list="10.10.0.1:6677">
<dynamic-load-provider>
<load-metric type="busyness"/>
</dynamic-load-provider>
</mod-cluster-config>
</subsystem>
...
...
<server-group name="SG1" profile="ha">
<system-properties>
<property name="mycluster.modcluster.balancer" value="SG1Balancer"/>
</system-properties>
<jvm name="default"/>
<socket-binding-group ref="ha-sockets"/>
</server-group>
<server-group name="SG2" profile="ha">
<system-properties>
<property name="mycluster.modcluster.balancer" value="SG2Balancer"/>
</system-properties>
<jvm name="default"/>
<socket-binding-group ref="ha-sockets"/>
</server-group>
....
And in host.xml (same as in slave and host):
....
<servers>
<server name="server-1" group="SG1" auto-start="true">
<socket-bindings port-offset="1"/>
</server>
<server name="server-2" group="SG2" auto-start="true">
<socket-bindings port-offset="2"/>
</server>
....
I need to point each virtual hosts to a specific server-group, so this is my solution for it:
www.vhost1.com -> SG1Balancer, which is attached to group=SG1, so it will load balance between:
jboss-instance-1's server-1
jboss-instance-2's server-1
www.vhost2.com -> SG2Balancer, which is attached to group=SG2, so it will load balance between:
jboss-instance-1's server-2
jboss-instance-2's server-2
Here's my httpd configuration sets:
loadbalancer.conf:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule slotmem_module modules/mod_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule advertise_module modules/mod_advertise.so
<IfModule manager_module>
Listen 0.0.0.0:6677
ManagerBalancerName ddrct-cluster
<VirtualHost *:6677>
ServerName RecetteDtvLb1
<Location />
Order deny,allow
Allow from 0.0.0.0
</Location>
# No server advertising
# we're using proxy-list
ServerAdvertise Off
KeepAliveTimeout 300
MaxKeepAliveRequests 0
EnableMCPMReceive
<Location /mcm>
SetHandler mod_cluster-manager
Order deny,allow
Allow from 0.0.0.0
</Location>
</VirtualHost>
</IfModule>
vhosts.conf:
ProxyRequests Off
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.vhost1.com
ProxyPass / balancer://SG1Balancer stickysession=JSESSIONID
ProxyPassReverse / balancer://SG1Balancer
ProxyPreserveHost On
ErrorLog "logs/vhost1_error.log"
CustomLog "logs/vhost1_access.log" common
</VirtualHost>
<VirtualHost *:80>
ServerName www.vhost2.com
ProxyPass / balancer://SG2Balancer stickysession=JSESSIONID
ProxyPassReverse / balancer://SG2Balancer
ProxyPreserveHost On
ErrorLog "logs/vhost2_error.log"
CustomLog "logs/vhost2_access.log" common
</VirtualHost>
Everything is running fine, deployed apps in G1 can be used through www.vhost1.com and vice versa for G2, the problem is all about session stickyness, here are the symptoms:
My browser is accepting JSESSIONID cookie, but having a content like this: KhH7gInyAFPsILN6mYDQ84Kf.jboss-instance-1:server-1 will not get my next request sticked to jboss-instance-1's server-1, the load balancer will switch my requests between jboss-instance-1's server-1 and jboss-instance-2's server-1 and each time it changes the JSESSIONID cookie content.
When i manually edit the content of JSESSIONID cookie (using firecookie plugin) to remove the server name like this: KhH7gInyAFPsILN6mYDQ84Kf.jboss-instance-1, my requests will be sticking on jboss-instance-1, leading to a correct behaviour
Did not get too much documentation about multi-vhost and multi-server-group clustering and load balancing configurations, it was my own guess to implement such configuration, i may get it wrong ... any help ?
Issue resolved, from KB182813:
Do not put the "-" character in your balancer name as it has been known to create sticky session issues
Do not use uppercase characters in your balancer name
Regarding node names
The relevant issue MODCLUSTER-435 was resolved in Nov 2014. It is safe to use upper case characters and dashes in any decent mod_cluster version, i.e. 1.3.x.
Regarding ProxyPass
One doesn't need to set anything ProxyPass related unless one wants to do something special. The aforementioned setting is redundant and weird. Mod_cluster uses mod_proxy as its backend, so it actually dynamically configures proxy pass balancer members for you. It makes sense to have your own ProxyPass additional setting if you wish to alter the balancer's behaviour in a custom way, e.g.
One needs to have static content served from the Apache HTTP Server while the dynamic one being proxied to Wildfly workers:
ProxyPassMatch ^/app/static/ !
ProxyPass /app balancer://qacluster stickysession=JSESSIONID|jsessionid nofailover=on
ProxyPass / !
ProxyPassReverse /app balancer://qacluster
ProxyPassReverseCookieDomain / /app/
ProxyPassReverseCookiePath / /app/
ProxyPreserveHost on

SSL between apache and JBoss

We have the next configuration:
one apache server with version 2.2.14.
two application servers with JBoss Application Server version 7.1.1 in domain mode.
We configure a virtual hosts and mod_cluster discover application servers without problem, but when I add the configuration for ssl then mod_cluster cannot discover application servers.
The file httpd-vhosts.conf is:
Listen <ip>:10001
MemManagerFile /var/cache/httpd
<VirtualHost <ip>:10001>
ErrorLog "/usr/IBMAHS/logs/error_ssl_log"
TransferLog "/usr/IBMAHS/logs/access_ssl_log"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "/usr/IBMAHS/pki/file.com.crt"
SSLCertificateKeyFile "/usr/IBMAHS/pki/file.com.key"
<Directory />
Order deny,allow
Allow from all
</Directory>
KeepAliveTimeout 60
MaxKeepAliveRequests 0
ManagerBalancerName other-server-group_d
ServerAdvertise On
AdvertiseFrequency 5
#EnableMCPMReceive
#This directive allows you to view mod_cluster status at URL http://<ip>:10001/mod_cluster-manager
<Location /mod_cluster-manager>
SetHandler mod_cluster-manager
Order deny,allow
Allow from all
</Location>
</VirtualHost>
Can anyone help me?
I assume you would like to have this setup up and running:
clients <-- SSL --> balancer <-- SSL --> AS7 workers
and that you are aware of severe performance drawback of its
balancer <-- SSL --> AS7 workers
part. The following setup works, yet one must be aware of the fact that connection between client and AS7 worker is not transparent and that the balancer acts more or less like a man-in-the-middle. If clients trust the balancer, balancer trusts the workers and workers trust the balancer, it's all good.
Here you go bro:
Apache HTTP Server with mod_cluster
MemManagerFile "/opt/httpd/cache/mod_cluster"
ServerName 10.16.94.122:2181
<IfModule manager_module>
Listen 10.16.94.122:8847
# As soon as it works, remove/change this...
LogLevel debug
<VirtualHost 10.16.94.122:8847>
ServerName 10.16.94.122:8847
<Directory />
Order deny,allow
Deny from all
# Obviously, testing purposes...
Allow from all
</Directory>
KeepAliveTimeout 60
MaxKeepAliveRequests 0
ServerAdvertise on
AdvertiseFrequency 5
ManagerBalancerName qacluster
AdvertiseGroup 224.0.5.188:23364
EnableMCPMReceive
SSLEngine on
SSLCipherSuite AES128-SHA:ALL:!ADH:!LOW:!MD5:!SSLV2:!NULL
SSLCertificateFile /opt/ssl/proper/server.crt
SSLCertificateKeyFile /opt/ssl/proper/server.key
SSLCACertificateFile /opt/ssl/proper/myca.crt
#SSLVerifyClient require
#SSLProxyVerify require
SSLProxyEngine On
SSLVerifyDepth 10
<Location /mcm>
SetHandler mod_cluster-manager
Order deny,allow
Deny from all
# Obviously, testing purposes...
Allow from all
</Location>
</VirtualHost>
</IfModule>
AS7 worker, standalone-ha.xml, could be applied to a proper in domain as well:
AS7 worker
+++
</extensions>
<system-properties>
<property name="javax.net.ssl.trustStore" value="/opt/ssl/proper/client-cert-key.jks"/>
<property name="javax.net.ssl.trustStorePassword" value="you-shall-never-know"/>
</system-properties>
<management>
+++
</management>
<profile>
+++
<subsystem xmlns="urn:jboss:domain:modcluster:1.1">
<mod-cluster-config advertise-socket="modcluster" connector="https">
<dynamic-load-provider>
<load-metric type="busyness"/>
</dynamic-load-provider>
<ssl key-alias="javaclient" password="you-shall-never-know" certificate-key-file="/opt/ssl/proper/client-cert-key.jks"
cipher-suite="AES128-SHA:ALL:!ADH:!LOW:!MD5:!SSLV2:!NULL" ca-certificate-file="/opt/ssl/proper/ca-cert.jks"/>
</mod-cluster-config>
</subsystem>
+++
<subsystem xmlns="urn:jboss:domain:web:1.5" native="false">
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true" enabled="true">
<ssl name="https" key-alias="javaclient" password="you-shall-never-know" certificate-key-file="/opt/ssl/proper/client-cert-key.jks"
cipher-suite="AES128-SHA:ALL:!ADH:!LOW:!MD5:!SSLV2:!NULL" protocol="TLS" verify-client="false"
certificate-file="/opt/ssl/proper/client-cert-key.jks" ca-certificate-file="/opt/ssl/proper/ca-cert.jks"/>
</connector>
<virtual-server name="default-host" enable-welcome-root="true">
<alias name="localhost"/>
<alias name="example.com"/>
</virtual-server>
</subsystem>
+++
</profile>
<interfaces>
+++
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
+++
<socket-binding name="https" port="8443"/>
+++
<socket-binding name="modcluster" port="0" multicast-address="224.0.5.188" multicast-port="23364"/>
+++
Let us know if it works for you. In future, you might actually target the JBoss mod_cluster forums directly :-)
Have you a sample configuration for standalone (not clustered) ?

How to configure JBoss 7 to serve different default war for specific hostnames (with SSL)

Here is my use case.
I want to use JBoss 7 to serve 2 different webapps (war) depending on the hostname which is used inside the HTTP request :
When I access to https://app1.mydomain.com/, JBoss must serve app1.war with the SSL certificate "app1.mydomain.com"
When I access to https://app2.mydomain.com/, JBoss must serve app2.war with the SSL certificate "app2.mydomain.com"
I would prefer that the appX.war were used as root context for each hostname (accessing to https://appX.mydomain.com/index.html would use the appX.war/index.html file), but I could accept going to https://appX.mydomain.com/appX/ to access my appX (X is 1 or 2).
Moreover I would want to use a single IP & port for that configuration, but this seems to be not possible (according to that SO answer & that one and that thread on JBoss forum) without using Appache HTTPD as a proxy. It would be the alternative but I would prefer not using it.
I tried to configure that with the standalone mode (and by using different IP). Here is an extract from my standalone.xml :
...
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="app1.mydomain.com" native="true">
<connector name="https-app1" protocol="HTTP/1.1" scheme="https" socket-binding="app1-https" secure="true">
<ssl password="pass1" certificate-key-file="${jboss.server.config.dir}/cert/app1.mydomain.com.key" protocol="TLSv1" verify-client="false" certificate-file="${jboss.server.config.dir}/cert/app1.mydomain.com.crt"/>
</connector>
<connector name="https-app2" protocol="HTTP/1.1" scheme="https" socket-binding="app2-https" secure="true">
<ssl password="pass2" certificate-key-file="${jboss.server.config.dir}/cert/app2.mydomain.com.key" protocol="TLSv1" verify-client="false" certificate-file="${jboss.server.config.dir}/cert/app2.mydomain.com.crt"/>
</connector>
<virtual-server name="app1.mydomain.com" enable-welcome-root="false" default-web-module="app1">
<alias name="app1.mydomain.com"/>
</virtual-server>
<virtual-server name="app2.mydomain.com" enable-welcome-root="false" default-web-module="app2">
<alias name="app2.mydomain.com"/>
</virtual-server>
...
<interfaces>
<interface name="app1.mydomain.com">
<inet-address value="10.0.0.1"/>
</interface>
<interface name="app2.mydomain.com">
<inet-address value="10.0.0.2"/>
</interface>
...
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="app1-https" interface="app1.mydomain.com" port="443" fixed-port="true"/>
<socket-binding name="app2-https" interface="app2.mydomain.com" port="443" fixed-port="true"/>
...
But that not seems to work as expected...
When I access to https://app1.mydomain.com/ I see my welcome file of my app1.war (I think this is due to the default-virtual-server attribute)
When I access to https://app1.mydomain.com/app1/ I see a 404 report (with HTML body content)
When I access to https://app1.mydomain.com/app2/ I see my welcome file of my app2.war
When I access to https://app2.mydomain.com/, https://app2.mydomain.com/app1/ or https://app2.mydomain.com/app2/, JBoss only answers an HTTP "404 Not Found" without any body HTML content, so my page is blank.
Does anyone has an idea ?
(I've also posted that question to the JBoss user forum)
I believe that you have two options.
Option 1: Using JBoss Virtual Hosts
In order to do this, you must add virtual host entries to the web sub service. Which you were doing.
I think the part that you missed was adding <virtual-host> tags to your jboss-web.xml files within your web apps.
Please reference the following link for quick instructions on setting up
Virtual Hosts With JBoss AS7.
Option 2: Using Apache
This would be the method I prefer, especially for a production use case. You have Apache be your web server and you have it proxy incoming requests to JBoss. Apache will also take care of SSL.
For example you can do this through mod_jk, which is a load balancer. mod_jk directs traffic to your application via the AJP connector, which should be available using the HA profiles in JBoss.
Since you are using mod_jk and HA profiles, you can go ahead and cluster your applications and load balance those clusters if you would like.
Please let me know if you have any further questions.
Finally, as it seems it's not possible directly using JBoss 7, I've used Apache HTTPD, non root context for my apps, and multiple IPs (the worst I would wanted) :
...
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
...
Listen 80
Listen 443
...
<VirtualHost IP1:80>
DocumentRoot "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/htdocs"
ServerName app1.mydomain.com:80
ServerAlias www.app1.mydomain.com
ServerAdmin admin#mydomain.com
ErrorLog "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/logs/app1.mydomain.com-error.log"
TransferLog "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/logs/app1.mydomain.com-access.log"
RewriteEngine On
RewriteRule ^/(.*)$ https://app1.mydomain.com/$1 [R]
</VirtualHost>
<VirtualHost IP1:443>
# General setup for the virtual host
DocumentRoot "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/htdocs"
ServerName app1.mydomain.com:443
ServerAlias www.app1.mydomain.com
ServerAdmin admin#mydomain.com
ErrorLog "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/logs/app1.mydomain.com-error.log"
TransferLog "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/logs/app1.mydomain.com-access.log"
ProxyPass /app1 ajp://localhost:8009/app1
ProxyPassReverse /app1 https://app1.mydomain.com/app1
RewriteEngine On
RewriteRule ^/$ /app1/ [R]
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
# Server Certificate:
SSLCertificateFile "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/conf/SSL/app1.mydomain.com.crt"
# Server Private Key:
SSLCertificateKeyFile "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/conf/SSL/app1.mydomain.com.key"
# Server Certificate Chain:
SSLCertificateChainFile "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/conf/SSL/ca-root.crt"
# SSL Protocol Adjustments:
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
# Per-Server Logging:
# The home of a custom SSL log file. Use this when you want a
# compact non-error SSL logfile on a virtual host basis.
CustomLog "C:/Program Files (x86)/Apache Software Foundation/Apache2.2/logs/app1.mydomain.com-ssl.log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
That's for app1.
For app2, just duplicate this configuration and replace app1 with app2 and IP1 with IP2.

How to deploy multiple Grails apps on one Tomcat + Apache?

I've read the several questions on StackOverflow and googled several hours but I can't find a complete and clear answer to my problem of deploying multiple Grails apps on one tomcat 5.5 (with Apache). Maybe someone can push me in the right direction or we can summarize a solution here.
The question Deploying multiple grails applications with Apache/Tomcat + Virtual Hosts looked promising but did not work. Maybe I need to do additional changes in Tomcat or Apache?
THE SITUATION:
In the webapps directory of Tomcat I have two war-files app1.war and app2.war which are getting unpacked by Tomcat and which I can access via domain1.com/app1 or domain1.com/app2 (I removed a previously used ROOT.war and the associated webapps/ROOT/ directory)
In the server.xml of Tomcat I have the following hosts:
<!-- Logger shared by all Contexts related to this virtual host. -->
<Logger className="org.apache.catalina.logger.FileLogger"
directory="logs" prefix="localhost_" suffix=".log"
timestamp="true"/>
<!-- Allow symlinks for the tomcat-docs webapp. This is required in
the Debian packages to make the Servlet/JSP API docs work. -->
<Context path="/tomcat-docs" docBase="tomcat-docs" debug="0">
<Resources className="org.apache.naming.resources.FileDirContext"
allowLinking="true" />
</Context>
</Host>
<Host name="domain1.com" appBase="webapps/app1" unpackWARs="true" autoDeploy="true"></Host>
<Host name="domain2.com" appBase="webapps/app2" unpackWARs="true" autoDeploy="true"></Host>
In Apache I have the following virtual hosts:
ServerName app1.com
JkMount /* default
DocumentRoot /var/lib/tomcat5.5/webapps/app1
<directory /var/lib/tomcat5.5/webapps/app1>
Options -Indexes
</directory>
LogLevel warn
ErrorLog /var/www/app1/logs/error.log
CustomLog /var/www/app1/logs/access.log common
The Problem:
I cannot directly access the two applications via domain1.com and domain2.com - what am I doing wrong?
Many thanks in advance,
Joerg.
I struggled with this a while back and managed to get something that works ok. It doesn't use mod_jk though, I opted for mod_proxy. I also had a slightly different set up in Tomcat (mine is version 6 btw), where I added multiple connectors as well as the Host declarations you have.
Try the following -
In tomcat server.xml:
<!-- I opted for a shared thread pool so both apps share same resources - optional -->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="250" minSpareThreads="40"/>
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8444"
executor="tomcatThreadPool"
proxyName="www.domain1.com"
proxyPort="80"/>
<Connector port="8082" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8445"
executor="tomcatThreadPool"
proxyName="www.domain2.com"
proxyPort="80"/>
<Host name="www.domain1.com" appBase="vhosts/domain1" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Alias>domain1.com</Alias>
</Host>
<Host name="www.domain2.com" appBase="vhosts/domain2" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Alias>domain2.com</Alias>
</Host>
In Apache:
<VirtualHost *:80>
ServerName www.domain1.com
ServerAlias www.domain1.com
ProxyRequests Off
ErrorLog /var/log/apache2/error-domain1.log
<Directory proxy:http://www.domain1.com:80>
Order Allow,Deny
Allow from all
</Directory>
<Proxy www.domain1.com:80>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8081/
ProxyPassReverse / http://localhost:8081/
ProxyPreserveHost On
</VirtualHost>
<VirtualHost *:80>
ServerName www.domain2.com
ServerAlias www.domain2.com
ProxyRequests Off
ErrorLog /var/log/apache2/error-domain2.log
<Directory proxy:http://www.domain2.com:80>
Order Allow,Deny
Allow from all
</Directory>
<Proxy www.domain2.com:80>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8082/
ProxyPassReverse / http://localhost:8082/
ProxyPreserveHost On
</VirtualHost>
Make sure mod_proxy is enable for your Apache server. It was a while ago when I got this working, so I'm sure if everything is needed in that config - once I get it working I tend to forget stuff :)
Hope that helps,
Chris.
we have two Grails Web App running in production under the same tomcat
That was easy to do with tomcat 6
The difference I see with your server.xml is the name of the apps
here what we have :
<Host name="www.domain1.com" appBase="[tomcat_root_dir]/www.domain1.com/webapps" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
</Host>
<Host name="www.domain2.com" appBase="[tomcat_root_dir]/www.domain2/webapps" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
</Host>
Then we have two directories domain1.com and domain2.com in tomcat root dir
In each directory, we have a webapps dir which holds only a ROOT.war file for each app
Hope that helps
Cheers
Grooveek