apachedockertomcatreverse-proxycontextpath

Apache proxy different context path cookie issue


I'm currently developing an application that will be deployed in a Docker container. The Docker contains a Tomcat that runs the application as ROOT.war, so at top level.

The idea is that when our users run the container, they may want to run several copies on a specific context path on their servers each, so for example:

https://somedomain.com/a and https://somedomain.com/b

My plan was to simply tell them to configure a proxy reverse like this:

ProxyPreserveHost On
RewriteEngine On

# Map https://somedomain/a to http://internalserver:9001
RewriteRule     ^/a$ /a/ [R]
ProxyPass        /a/ http://internalserver:9001/
ProxyPassReverse /a/ http://internalserver:9001/

# Map https://somedomain/b to http://internalserver:9002
RewriteRule     ^/b$ /b/ [R]
ProxyPass        /b/ http://internalserver:9002/
ProxyPassReverse /b/ http://internalserver:9002/

Where 9001 and 9002 are the ports of the two Docker containers running copies of my application.

Now, this makes the application run, but there are issues with cookies, as the context path on the server in Tomcat is always empty and therefore there are session issues.

I've seen several questions about similar situations, but in all cases, people are able to either change the public path or the path within Tomcat to make them match. In my case, I simply cannot do that, because I'd be dictating which path the users of our software would have to use.

Here are examples of such questions:

https://serverfault.com/questions/311994/how-to-proxy-context-to-different-backend-context-in-apache https://serverfault.com/questions/495017/how-do-i-ensure-the-context-path-is-the-same-when-accessing-a-web-app-via-apache Tomcat behind an apache proxy error on path


Is there any way to make this setup work properly?

Can I change the proxy configuration to forward the context path somehow?

Are there other options?


Solution

  • Ok, I found a quite simple solution. Maybe it'll help someone else, so I'll post it here:

    I figured out that there's a proxy config option called ProxyPassReverseCookiePath which is meant to be used for exactly what I was trying to achieve, so I changed the config to this:

    RewriteRule      ^/a$ /a/ [R]
    <Location /a/>
      ProxyPass        http://internalserver:9001/
      ProxyPassReverse http://internalserver:9001/
      ProxyPassReverseCookiePath / /a
    </Location>
    RewriteRule      ^/b$ /b/ [R]
    
    <Location /b/>
      ProxyPass        http://internalserver:9002/
      ProxyPassReverse http://internalserver:9002/
      ProxyPassReverseCookiePath / /b
    </Location>
    

    This maps every cookie path coming from the internal server with a path of / to /a or /b depending on the application, which is exactly what I wanted. The application itself now always sets the cookie path to just / if there is no context path available. The reverse proxy then maps it back to wherever it was requested from.