6

I have an Apache 2 frontend, that serves two kinds of requests:

  • Requests to the root folder (e.g. http://mysite.com/ and http://mysite.com/help) are served by the apache itself (PHP/Wordpress).
  • Specific requests to the '/playapp' subfolder are forwarded to Play! via a reverse proxy via mod-proxy:

mod-proxy.conf

ProxyPass        /playapp/ http://localhost:9000/
ProxyPassReverse /playapp/ http://localhost:9000/

The end result is that requests to say http://mysite.com/playapp/Controller/action reach the Play server as http://localhost:9000/Controller/action

Now, Play! serves the page correctly, but all links, including javascript, css and links to other pages, are broken. For example, if a view uses:

#{stylesheet 'style.css' /}

Then the rendered result is

<link rel="stylesheet" type="text/css" href="/public/stylesheets/style.css" charset="utf-8" ></link>

So the end user tries to fetches http://mysite.com/public/stylesheets/style.css, which returns a 404 because it's not actually part of the Play! app.

What's the correct way to configure Apache + Play to play along here?

The result I'm looking for is for Play! to return URLs such as this in the final rendered HTML (or perhaps for Apache to rewrite the URLs accordingly): http://mysite.com/playapp/public/stylesheets/style.css

Also, I do need some ability to link outside of the Play app. For example, I want the home route (/) to be mapped to my absolute root (http://mysite.com/), not to Play's root.

ripper234
  • 222,824
  • 274
  • 634
  • 905
  • 1
    NOt really answering your question but you should use subdomains instead of trailing folders names in your url. Configuration will be much easier – i.am.michiel Jan 04 '12 at 10:13
  • Here's a link someone sent me, I'll check it out when I get a chance: http://www.apachetutor.org/admin/reverseproxies – ripper234 Jan 04 '12 at 11:22
  • ahah I can see what this question is related to ;-) Not a solution, but why aren't you using nginx or lighthttp as a frontend?? Much more suited for the job(lighter and faster) and easier to configure. – Stefano Jan 04 '12 at 13:26
  • and I agree with @Zenklys (and with my other comment!): subdomains are easier and way more clear to put several apps together. – Stefano Jan 04 '12 at 13:27
  • I am currently setting up a test with Apache/nginx in front to test performance, but from what I've seen until now, nginx (or lighthttp) is going to be so much faster than apache. – i.am.michiel Jan 04 '12 at 16:01

4 Answers4

3

First, something important: apache2 can't (easily) change links in the pages. So Play must provide the right ones already.

Using subdomain will make all of this completely transparent, but let's tackle your question.

You really have two points in your question,

Fix subfolders for static resources

Using routes just set

GET /playapp/public/ staticDir:public

Are you using http.path ?

I think reverse should take it into account....

outside links

  • Also, I do need some ability to link outside of the Play app. For example, I wan the home route (/) to be mapped to my absolute root (http://mysite.com/), not to Play's root.

Well this sounds easy: if it's outside the play app then you are not using a reverse url, so just put the absolute path in your links... or are you using a reverse? If so, can you provide an example?

Stefano
  • 18,083
  • 13
  • 64
  • 79
  • 1
    Thanks, I finally got around to testing this. http.path was the key. I put my Play app on the same path the proxy was mapping to (just on a different port of course), and fixed a few URLs (in css files) to be relative instead of absolute. – ripper234 Jan 10 '12 at 17:22
1

Have you configured your application.conf with

XForwardedSupport=127.0.0.1

and your apache.conf

ProxyPreserveHost on

An alternative option if that does not work is from a previous post.

I believe the answer I have given in this other post would be relevant to your situation

how to use "war.context" in Configuration file of Play Framework ?

Basically, it means reading some value from the properties file, and the pre-pending that value to all of your routes. It is the suggested method for servlet deployment where the path changes from that which the default play setup uses.

Community
  • 1
  • 1
Codemwnci
  • 54,176
  • 10
  • 96
  • 129
1

It'll be silly to expect Apache to rewrite HTML, JS and CSS files. How about SWF files or dynamically constructed URLs in JS? Anyway, you get my drift. The ProxyPassReverse documentation states:

Only the HTTP response headers specifically mentioned above will be rewritten. Apache will not rewrite other response headers, nor will it rewrite URL references inside HTML pages. This means that if the proxied content contains absolute URL references, they will by-pass the proxy. A third-party module that will look inside the HTML and rewrite URL references is Nick Kew's mod_proxy_html.

As one of the comments suggested, an approach much more likely to succeed is to configure another DNS name (e.g. play.ripper234.org) and create a configuration such as:

<VirtualHost>
ServerName play.ripper234.org
ProxyPass / http://localhost:9000/
ProxyPassReverse / http://localhost:9000/
</VirtualHost>

Even this wouldn't "save" you if the files returned by Play! would use a fully-qualified URL such as http://localhost:9000/ or http://www.yahoo.com/ or whatnot.

As for recommending you a different web server, I actually think you should stick to Apache. It has very sensible and powerful configuration, and it's fast enough for all your needs. In general, Apache is not particularly slow. There are web servers better suited for embedded use, and there are web servers better suited for serving lots of static pages as fast as possible. It's nothing you should worry about until you become really big.

Ilya
  • 5,533
  • 2
  • 29
  • 57
0

Play 1.x support a "http.path" setting.

Play 2.1-snapshot already supports a configuration setting "application.context" to put the application context under a sub directory.

Please check this commit:

Allow root context using [application.context] configuration setting.

nn.
  • 39
  • 1
  • 7