Apache2 Reverse Proxy, why does my solution never match the example?
-
17-06-2021 - |
Question
I need to make a reverse proxy back to a tomcat server running a grails application. I have always seen reverse proxy examples like this:
ProxyRequests Off
ProxyPass / http://localhost:8080/appname/
ProxyPassReverse / http://localhost:8080/appname/
ProxyPreserveHost On
In all my apps though, when I do that the page comes up and my statics get loaded like this with the context: /appname/static/[jsapp.js][mycss.css]
so consequently styling and functionality are lost. So my workaround is has been to do this:
ProxyRequests Off
ProxyPass /appname/ http://localhost:8080/appname/
ProxyPass / http://localhost:8080/appname/
ProxyPassReverse /appname/ http://localhost:8080/appname/
ProxyPassReverse / http://localhost:8080/appname/
ProxyPreserveHost On
which I guess is a reverse-reverse-proxy; either way it seems hacky and has (what i think is) a side affect; it creates the URL with the tomcat context in it: http://servername.com/appname/user/username instead of http://servername.com/user/username. I would much prefer the later if its possible without losing the styling.
NOTES:
- When i go to the base URL:http://servername.com it works fine, any link i click on after that puts the "/appname/" name in the URL.
- I believe that I could resolve this by making the app on tomcat the ROOT app, however, I would prefer not to.
- This example is using HTTP, I normally use AJP protocol, but I tried HTTP last just for kicks
- This is in a NameVirtualHost configuration.
- Apache 2.2.15, Tomcat 7.0.27, CentOS release 6.2 (Final), java version "1.7.0_04", Grails 2.0.4
Any thoughts on what I need to be doing differently?
Thanks.
Solution
There are several ways, how to solve this situation. I am using vhosts inside TomCat, so I eliminate the application name in the URL. Add this to your server.xml
<Host name="myapp.com" appBase="myappbase" unpackWARs="true" autoDeploy="false">
<Alias>www.myapp.com</Alias>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="myapp_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context path="/thumbnails" docBase="/var/www/myapp/thumbnails" reloadable="true">
</Host>
in your $TOMCAT_HOME create a directory "myappbase", where you upload your application WAR as ROOT.war. Your application is available via http://myapp.com:8080/.
Your proxy configuration is than very simple ;-) You can also make more vhosts in 1 TomCat.
In the aforementioned configration is also an directory alias (thumbnails), which is accessible via http://myapp.com/thumbnails/ and you can use it in GSP via:
${ resource( dir: 'thumbnails', file: 'image01.png' ) }
And the last point, which can help you is setting a "static" directories in UrlMappings.groovy. These directories are ignored when translation URL to controllers and vice versa:
static excludes = [
'/css*', '/js*', '/thumbnails*'
]