James Murphy
James Murphy

Reputation: 798

How do I define Play assets and APIs to be served from a different sub-directory in production?

I'm using the Play 2 Framework. All assets are rendered correctly locally (but not production) if I'm not using versioned assets.

I have a requirement that locally assets are served from localhost:9000/assets/* however when in production the assets are to be served from www.domain.com/subfolder/assets/*

I also need to ensure that APIs are served from localhost:9000/api/* and www.domain.com/subfolder/api/* in a similar fashion in production. This is because there is already an application running on www.domain.com and it's assets are written and served using a totally different technology (PHP as opposed to Java / Scala).

My routes in play defines:

# Map static resources from the /public folder to the /assets URL path
GET     /assets/v/*file               controllers.Assets.versioned(path="/public", file: Asset)

Assets are loaded in like so in a header.scala.html file:

<link rel="stylesheet" href="@routes.Assets.versioned("template/css/bootstrap.css").absoluteURL()" />
<link rel="stylesheet" href="@routes.Assets.versioned("stylesheets/main.css").absoluteURL()" />

I'm loading js assets in a footer.scala.html file like so:

<script src="@routes.Assets.versioned("template/js/jquery.min.js").absoluteURL()"></script>
<script src="@routes.Assets.versioned("template/js/bootstrap.min.js").absoluteURL()"></script>

<script type="text/javascript" src="@routes.Assets.versioned("template/angular/angular.js").absoluteURL()"></script>
<script type="text/javascript"
src="@routes.Assets.versioned("template/angular/angular-animate.js").absoluteURL()"></script>
<script type="text/javascript"
src="@routes.Assets.versioned("template/angular/angular-cookies.js").absoluteURL()"></script>
<script type="text/javascript"
src="@routes.Assets.versioned("template/angular/angular-route.js").absoluteURL()"></script>
<script type="text/javascript"
src="@routes.Assets.versioned("template/angular/angular-resource.js").absoluteURL()"></script>
<script type="text/javascript"
src="@routes.Assets.versioned("template/angular/angular-sanitize.js").absoluteURL()"></script>

<script type="text/javascript" src="@routes.Assets.versioned("javascripts/app.js").absoluteURL()"></script>
<script type="text/javascript"
src="@routes.Assets.versioned("javascripts/appController.js").absoluteURL()"></script>

<script type="text/javascript" src="@routes.Assets.versioned("javascripts/moment.js").absoluteURL()">    </script>

My play app is served up using a reverse proxy configuration in Apache which correctly serves up from www.domain.com/subfolder

However, the api's and assets are still wanting to be loaded from www.domain.com and not www.domain.com/subfolder

How can I load in assets correctly so they load correctly for both development and production?

I've looked at https://www.playframework.com/documentation/2.5.x/AssetsOverview as I say the assets are loaded in production in the /assets folder and not subfolder/assets

Any help much appreciated!

Update

I've tried the following as suggested by Kim's answer:

ProxyPreserveHost On
ProxyPass /sportsbook http://127.0.0.1:9000 retry=0
ProxyPassReverse /sportsbook http://127.0.0.1:9000 retry=0

ProxyHTMLEnable Off
ProxyHTMLURLMap http://localhost:9000 /sportsbook
<Location /sportsbook/>
    ProxyPassReverse http://localhost:9000/
    SetOutputFilter proxy-html
    ProxyHTMLURLMap /           /sportsbook/
    ProxyHTMLURLMap /sportsbook            /sportsbook
</Location>

This however breaks the main site now (with no css or js working). Any ideas?

Upvotes: 1

Views: 168

Answers (2)

James Murphy
James Murphy

Reputation: 798

I couldn't figure out the issue above and apparently it's easier just to serve the assets locally from localhost:9000/subfolder.

So basically I just changed all the assets to point to that directory instead both locally and in production with a proxy redirect in apache for localhost:9000/subfolder to website.com/subfolder

Upvotes: 0

Kim Stebel
Kim Stebel

Reputation: 42047

It's probably easier and more flexible to rewrite your request in the reverse proxy rather than change the paths in your application. The apache docs show you how to do that using mod_rewrite. It could be as simple as

RewriteRule "^/subfolder/(.*)" "http://playapp.example.com/$1" [P]

Upvotes: 0

Related Questions