Nginx – Reverse proxy for 3 websites all on root context

nginxreverse-proxy

We're struggling with the following problem and trying to understand what's the best way to deal with this. The general goal is such:

--> example.com/app1         -->  app1.com/
--> example.com/app1/images  -->  app1.com/images

--> example.com/app2         -->  app2.com/
--> example.com/app2/images  -->  app2.com/images

--> example.com/app3         -->  app3.com/
--> example.com/app3/images  -->  app3.com/images

We've considered the following solutions, some of them work and others don't. We're trying to figure out what's the best way to do this because we're by no means experts. The tool we've been using so far is Nginx to do the reverse proxy, but the tool doesn't really matter, we're open to anything.

Solution 1

Nginx rewrites the body text to add "app1" for app1 requests, etc. As in the example above, there's a request for app1 and an index.html comes back. That index.html in turn has some tag that looks like <img src="images/hello.png" /> file. This obviously won't work, so we rewrite the body (i.e. the index.html) to say <img src="app1/images/hello.png" />.

Problem with Solution 1

We have to be really good about how we craft the body rewrite rules otherwise we could rewrite something we didn't intend and then break some JS or HTML. This solution also doesn't work for some of the JS code (we're using Angular) which doesn't implicitly write out the location of the views and is rather put together by the framework itself.

Solution 2

Move every app from the root to it's own folder. This means any img or other request will update to <img src="app1/images/hello.png" />.

Problem with Solution 2

We have to change all the existing 3 websites to request resources from their respective new roots.

Any help would be greatly appreciated, thanks in advance.

Best Answer

Ideally you can redeploy your applications such that each application is installed in http://app<n>.com/app<n> instead of the document root.

If not maybe you can have the links made relative, instead of linking to /images/logo.png link to ../images/logo.png or images/logo.png or ../../images/logo.png depending on the page that's served, which will translate correctly in a Reverse Proxy situation.

Obviously using subdomains for each application will work well enough, reverse proxy everything on app<n>.example.com/ to your internal app<n>.com/

Normally a reverse proxy will not rewrite the contents of the response body it receives from the server the request was forwarded to, but apache will allow you to do so:

<Location /app1/>
   ProxyPass http://app1.com/
   ProxyPassReverse http://app1.com/ 
   # rewrite the reponse body  
   AddOutputFilterByType SUBSTITUTE text/html
   Substitute "s|/images/|/app1/images/|i" 
</Location>
Related Topic