Question

I have multiple grails application running on a tomcat server, using the ajp protocol. On the same server I have apache running as a front end to those tomcat applications. apache configuration like this:

ProxyPass /example1/ ajp://localhost:8082/example1/
ProxyPassReverse /example1/ ajp://localhost:8082/example1/
ProxyPass /example2/ ajp://localhost:8082/example1/
ProxyPassReverse /example2/ ajp://localhost:8082/example2/

I want example1 to run as the root context

ProxyPass / ajp://localhost:8082/example1/

this does not work. All Static content is broken. the web page text renders, by the images would point to: /example1/images/myimage.jpg the image would get resolved if you go to: /images/myimage.jpg

I have tried many things to avoid deploying example1 as ROOT.war. but that seems to be the only way to resolve this issue. This is not sufficient for my need.

on the grails side, I've tied removing the ${appName} from the server url, to look like: grails.serverURL = "http://apacheajp.example.com/"

I've added grails.app.context=/ to application.properties, this did not work either.

the ultimate goal here is to use this apache to server for multiple subdomains. I would want example1.example.com (a alias to apacheajp.example.com) to resolve to the example1 app. Similarly, I would want example2.example.com to act the same way for the example2 app. This explains why deploying as ROOT would be undesirable.

the server I use is RHEL6

this post here best describes the same issue I am having: http://grails.1312388.n4.nabble.com/Grails-context-big-problem-with-apache-mod-proxy-td1392448.html

Was it helpful?

Solution

As Mark Thomas suggest, it's easiest to deploy your application with the same context root on Tomcat as you want it to have on Apache. So for context root '/' this means to deploy as ROOT.war on Tomcat. To have multiple apps with context root '/' but different subdomains, the easiest solution is probably to run multiple instances of Tomcat, one for each application, and deploy all of them as ROOT.war. This is how we do it. This also means it's easier to do upgrades without taking down all applications.

Each Tomcat instance will need its own shutdown port, http port and ajp port in conf/server.xml.

OTHER TIPS

If you change the path in ProxyPass then there are a bunch of other issues you need to take into consideration as well. These are sufficiently tricky / expensive that it is usually far easier to deploy the application as ROOT.war

Given you can't / won't do that, you'll need to consider the following:

  • Add a ProxyPassReverse directive to fix some HTTP response headers
  • Add a ProxyPassReverseCookiePath directive to fix any cookies
  • Use mod_headers to modify any other headers that contain the incorrect path reference
  • Use mod_substitute to correct the context path in any response bodies

That is usually enough but it can take some time to track down all the things that you need to change. I really would encourage you to just rename the WAR to ROOT.war. What is stopping you?

So the only way to resolve the problem is by doing what rlovtang suggested in the first reply, and deploy the application as ROOT.war, by using a virtual host

see my other question: connect to alternate alternate host alias with ajp protocol

Apache

NameVirtualHost *:80


<VirtualHost *:80>
    ServerName app1.myserver.com
    ProxyPass / ajp://tomhost1:8009/
    ProxyPassReverse / ajp://tomhost1:8009/
</VirtualHost>

<VirtualHost *:80>
    ServerName app2.myserver.com
    ProxyPass / ajp://tomhost2:8009/
    ProxyPassReverse / ajp://tomhost2:8009/
</VirtualHost>

Tomcat

<Host name="tomhost1" appBase="tomhost1" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false" >
    <Alias>app1.myserver.com</Alias>
</Host>

<Host name="tomhost2" appBase="tomhost2" unpackWARs="true"
autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false" >
    <Alias>app2.myserver.com</Alias>
</host>

/etc/hosts

on host, myserver.com

127.0.0.1       localhost       tomhost1     tomhost2

on client

188.555.555.555  app1.myserver.com   app2.myserver.com

you wont have to mess with your client hosts file if there is a CNAME or ANAME setup for app1 and app2. If the server and the client are the same computer add the app1 and app2 host aliases to localhost alias. for tomcat, make sure there are directories for tomhost1 and 2. if you are deploying a grails app as a ROOT.war, make sure your server url looks like

grails.serverURL = "http://app1.myserver.com/"

create the war file, and place it in the tomhost1 folder.

I was able to solve the issue I had with broken images. A example taken from here: http://www.wthr.us/2010/01/25/improve-grails-performance-with-static-resources/

NameVirtualHost *:80

<VirtualHost *:80>
            ServerName subdom1.example.com
            ProxyPass / ajp://localhost:8082/app1/
            ProxyPassReverse / ajp://localhost:8082/app1/
            RewriteEngine on
            RewriteRule ^/app1/images/(.*) /home/tomcat/webapps/app1/images/$1
            RewriteRule ^/app1/css/(.*) /home/tomcat/webapps/app1/css/$1
            RewriteRule ^/app1/js/(.*) /home/tomcat/webapps/app1/js/$1
</VirtualHost>

This should be good enough.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top