Nginx Reverse Proxy with SSL offloading and Apache Tomcat backends

Nginx SSL offloading

In our current native Docker environment, we are using Nginx as our border controller (link) to get the traffic and the user sessions (sticky) managed with our Apache Tomcat servers. But together with our developers we found out that there is a major problem with https encryption on Nginx and using Apache Tomcat http connector as backend interface.

The problem

If the Apache Tomcat is not configured correctly (server.xml and web.xml) some of the automatically created redirect links (created by Apache Tomcat himself) in application will still point to http resource urls. This will lead to double requests and of course to a not working application if you are using a modern browser like Chrome (insecure content in secure context).

The solution(s)

Apache Tomcat server.xml

You have to modify the Apache Tomcat server.xml to add the parameters scheme="https", secure="true", proxyPort="443" . Afterwards your http connector setting should looks like the following code. Afterwards the request object in the Apache Tomcat will have the correct scheme.


Usually you will enable the x-forwarded-for header in the Nginx configuration. Afterwards on the backend you can retrieve the header inside your, in case of Apache Tomcat, Java code. But this would be a manual way to do it. To be compatible with this header out of the box, you can add a filter to you web.xml. Afterwards the x-forwarded-proto will be automatically set inside the Apache Tomcat request object. Here is the needed part of the web.xml.


After some research we figured out on how to configure Apache Tomcat to work seamlessly with Nginx as reverse proxy in conjunction with Apache Tomcat backends.

GitHub and animated gifs…

For our n0r1skcom/echo DockerHub image we wanted to add a gif (see above) with console output to the corresponding GitHub project README.

But that wasn’t that easy as we thought because GitHub caches images with atmos/camo and that brings in some problems with bigger gif’s…

So we had to disable image caching via the http headers of our source image but these images are located in our WordPress media library and we didn’t want to disable image caching in general.

The solution for us was to configure the serving webserver (in our case Apache) to set some caching/expiry headers via LocationMatch directive and a fancy regex.
Our regex includes all pictures with the filename prefix “nocache_” – so every other image uploaded isn’t touched in any way.

Apache configuration sample

WordPress SSL (https) and Reverse Proxy (Nginx, Apache httpd)

As you can see, this blog is accessible through SSL (https) encryption only. Normally this is not a huge problem but WordPress is a little bit clunky if it comes to a setup that also includes a reverse proxy.


The following text is a sum up some pages which can be found on the internet but often lacks information. This WordPress blog that you are currently reading is running on an Apache httpd on localhost. In front of it, there is a second Apache httpd which acts as reverse proxy for different tasks. One of these tasks is to offload SSL (https) encryption.

WordPress installation

In the described setup you should first install the WordPress software on http (port 80) without SSL. If you enable SSL at this time chances are good that you end up in a redirect loop.

Configure SSL (https)

On the reverse proxy configure SSL as usual but be aware, that you have to set RequestHeader set X-Forwarded-Proto "https" inside the SSL virtual host! This information is important as otherwise the URL’s generated by WordPress will be http links and therefore you will get browser warnings later. Do not force a permanent redirect from http to https at this point or you will not be able to install the necessary WordPress plugin which take care on your URL’s.

After you have enabled basic https support install the WordPress extension SSL Insecure Content Fixer and configure it to use the X-Forwarded-Proto header. Afterwards you have to modify the wp-config.php to reflect this settings. If you want use Jetpack, you also have to specify SERVER_PORT otherwise you will receive a error message on during the configuration of your social media connections (There was an error retrieving your site settings.). You also have to force admin SSL usage.

Hopefully this will help some people out there to get this up and running. If this config does not help you, leave a comment!


Apache http reverse proxy config

Nginx reverse proxy (in an Docker environment)

WordPress wp-config.php