Using Apache as a Reverse Proxy for Spring Boot Embedded Tomcat
A common setup for Java web applications is to run Tomcat behind a web server like Apache in a reverse proxy configuration. This allows Apache to handle all incoming and outgoing traffic between users and the Tomcat web application.
In the above diagram, the Tomcat server runs on localhost interface (127.0.0.1) with default port 8080. Communication between Apache and Tomcat processes is unencrypted which is acceptable since they are both running on the same server.
How does the web application know which URL it lives on? It won’t know unless Apache forwards the HTTP headers to Tomcat.
This is valuable in a number of use cases:
- Application needs to e-mail users with links for password resets and account confirmations
- Multi-tenancy has been implemented and we are using a subdomain to identify the customer
Here we tell Spring Boot to run on localhost with default port of 8080. We also specify that it should use the headers given to it by Apache which we’ll configure in the next section.
server.address=127.0.0.1 server.port=8080 server.use-forward-headers=true
Apache Virtual Host
We add the below directives to our virtual host. This example assumes that all content is served from our Spring application (including static files).
ProxyPreserveHost on RequestHeader set X-Forwarded-Proto https RequestHeader set X-Forwarded-Port 443 ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/
With Spring Boot, we can add HttpServletRequest request to any controller method parameter in order to gain the ability to inspect the request.
We can use the following methods to determine our URL:
- getScheme() — returns the protocol (http or https)
- getServerName() — returns the hostname (e.g. cloud.myapp.com)