Spring Boot
Tomcat
Apache Proxy
Java
Web Server Configuration

Spring Boot with embedded Tomcat behind Apache proxy

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Running Spring Boot with embedded Tomcat behind Apache HTTP Server is a common production pattern. Apache handles TLS termination, request routing, and static concerns, while Tomcat serves the application. The main challenge is preserving original request context, especially scheme, host, and client IP, so redirects, generated links, and security logic stay correct. Proper forwarding headers and timeout alignment are essential for stable behavior. This guide shows a practical reverse-proxy setup, the Spring Boot properties that matter, and checks you should run before shipping to production.

Core Sections

Configure Apache as reverse proxy

A minimal Apache virtual host can forward traffic to Tomcat on localhost.

apache
1<VirtualHost *:443>
2    ServerName app.example.com
3
4    SSLEngine on
5    SSLCertificateFile /etc/ssl/certs/app.crt
6    SSLCertificateKeyFile /etc/ssl/private/app.key
7
8    ProxyPreserveHost On
9    RequestHeader set X-Forwarded-Proto "https"
10    RequestHeader set X-Forwarded-Port "443"
11
12    ProxyPass        / http://127.0.0.1:8080/
13    ProxyPassReverse / http://127.0.0.1:8080/
14</VirtualHost>

Enable modules such as proxy, proxy_http, headers, and ssl.

Make Spring Boot trust forwarded headers

Spring needs to read forwarded headers so URL generation and redirect logic use public HTTPS endpoints.

For modern Boot versions:

properties
server.forward-headers-strategy=framework

For older setups, use Tomcat remote IP configuration if needed:

properties
server.tomcat.remoteip.protocol-header=x-forwarded-proto
server.tomcat.remoteip.remote-ip-header=x-forwarded-for

When this is wrong, apps often redirect from https to http unexpectedly.

Preserve client IP and security context

If you rely on rate limiting, audit logs, or geo rules, ensure X-Forwarded-For is propagated and trusted only from known proxies.

java
1@Bean
2public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() {
3    FilterRegistrationBean<ForwardedHeaderFilter> bean =
4            new FilterRegistrationBean<>(new ForwardedHeaderFilter());
5    bean.setOrder(0);
6    return bean;
7}

Use this only when needed and pair it with network-level restrictions so clients cannot spoof forwarding headers directly.

Align operational settings

Proxy and app timeouts should be consistent. If Apache times out sooner than Tomcat, users see proxy errors while the backend is still processing. Also configure max request size and upload buffers on both sides to avoid inconsistent failures.

For troubleshooting, compare:

  • Apache access/error logs
  • Spring Boot access logs
  • Upstream response timing metrics

This quickly reveals whether failures occur at proxy, network, or application layer.

Common Pitfalls

  • Forgetting X-Forwarded-Proto and getting incorrect absolute URLs or insecure redirect loops.
  • Trusting forwarded headers from untrusted networks, which can enable spoofed client IP behavior.
  • Mismatched timeout settings between Apache and Tomcat, causing intermittent 502 or 504 responses.
  • Using ProxyPass rules that accidentally bypass static assets or health endpoints.
  • Disabling host preservation and breaking virtual-host-aware application logic.

Production Readiness Check

Before closing the task, run a short validation loop on representative inputs and one intentional failure case. Confirm that your code path behaves correctly for normal data, empty data, and malformed data. Capture at least one measurable signal such as runtime, memory use, or error rate, then compare it to your baseline so regressions are visible. Keep this check lightweight so it can run in local development and CI without slowing feedback too much. A simple checklist plus one executable smoke test prevents most regressions after refactors and library upgrades.

text
11. Run happy-path example
22. Run edge-case example
33. Run failure-path example
44. Capture one performance or reliability metric
55. Verify output format and error handling

Summary

Spring Boot behind Apache proxy is robust when request context is forwarded correctly and both layers are configured consistently. Set Apache proxy headers, tell Spring Boot to honor them, and verify client IP and scheme handling in logs. Treat timeouts and request limits as an end-to-end contract rather than isolated settings. With these fundamentals in place, embedded Tomcat behind Apache is a reliable deployment model for many Java web services. Add one automated smoke test that asserts forwarded scheme and host values so proxy regressions are caught before release.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.