Tomcat with ORDS running APEX behind a reverse proxy

A while ago I posted a guide how to set up nginx as a reverse proxy in front of tomcat to run ORDS and APEX. See the post here.

An open problem was that APEX was still thinking it runs on port 80 with http, while nginx was running https on port 443.

The fix to this is editing tomcats server.xml file and adding proxyPort and scheme (documentation) to the connector:

Restart tomcat and everything looks fine !

Why is that even important? Everything seems to work fine, anyways.

In some situations APEX internally creates a redirect to a different URL path, e.g. during Authentication using Social-Login it will redirect to …/ords/apex_authentication.callback… . At this redirect APEX constracts the full URL using protocol and port information from above displayed CGI variables and would hence redirect to http and port 80 instead of https.

8 thoughts on “Tomcat with ORDS running APEX behind a reverse proxy

  1. Well, this approach has two downsides from my point of view:
    1) it does not fix the SERVER_NAME, should still be Nginx server name (in many setups localhost)
    2) a bit inflexible because you hardcode the proxy name into the Tomcat setup. But what if you have multiple proxies accessing your APEX instance … from the inside AND from the outside. This will not work.

    The easiest way would actually be to use an ajp proxy instead of an http proxy … this is the primary advantage of that:

    // these settings work in Apache as reference, not in nginx:
    ProxyPass /ords ajp://localhost:8009/ords timeout=500
    ProxyPassReverse /ords ajp://localhost:8009/ords

    Then you don’t have to worry about it all.

    But if you want to use an http proxy for whatever reason, this is the way to fix it in Apache http server:
    # fix http proxy settings for proxy host and protocol, e.g. when the
    # proxy host is vm1 and the port is 443, the default for https
    ProxyPreserveHost On
    RequestHeader set Host “vm1:443”
    ProxyPass /ords http://localhost:8080/ords timeout=500
    ProxyPassReverse /ords http://localhost:8080/ords

    Cheers,
    ~Dietmar.

  2. Hi Dietmar,
    thanks for taking the time to elaborate on this topic, and you are right, the AJP protocol fixes all the reverse proxy problems. This is what we use with Apache webservers.
    Unfortunately nginx doesn’t offer built-in AJP, thats why we fall back to HTTP in this case.
    I did blur the SERVER_NAME in my examples above, but they are actually correctly representing the outside server name, as defined by nginx. This is being transported correctly to tomcat with our nginx setup as seen in http://www.oracle-and-apex.com/the-oracle-apex-reverse-proxy-guide-using-nginx/, simply by using this line:

    proxy_set_header Host $host;

    As you see, there is no hardcoding involved :-)

  3. Perfect!

    Yes, using the “Host” http variable is the proper workaround for http proxy settings :).

    Cheers,
    ~Dietmar.

  4. Ok, now I understand the issue.
    Could you please try to use

    proxy_set_header Host $host:$port
    (I don’t know the proper syntax here).

    in your setup … then the change in server.xml will be obsolete I believe.

    In the http header variable “Host” you can put the port, too.
    In my case it was: vm1:443

    Does it work?

  5. >As you see, there is no hardcoding involved :-)
    Not quite, you still assume https and the default port 443, but it could be 8443 or any other.

    Just sayin’

  6. Hi Peter, thanks for your posts on APEX and NGINX / Apache proxying! Very useful!

    I like the lightweight NGINX with ORDS standalone (jetty) approach, but still facing some issues in my environment. Adding port number to NGINX proxy_set_header host setting changed the SERVER_PORT setting, but REQUEST_PROTOCOL still stays http. This results in strange redirects using the ssl port with HTTP scheme.

    Did you manage to switch the REQUEST_PROTOCOL setting to HTTPS?

    Cheers, Philipp!

Leave a Reply

Your email address will not be published. Required fields are marked *