While ProxyPass
handles the forwarding of requests to backend servers, ProxyPassReverse
modifies response headers from the backend to match the proxy server's domain. They serve complementary but distinct purposes:
# Forwarding requests to backend
ProxyPass /app/ http://backend-server:8080/
# Modifying response headers from backend
ProxyPassReverse /app/ http://frontend.example.com/app/
You must include ProxyPassReverse
when:
- The backend generates absolute URLs in responses
- Location headers need rewriting
- Content-Location headers require modification
- Redirects (3xx responses) occur from the backend
Basic Configuration Example:
# Without ProxyPassReverse (potential issues)
ProxyPass /service http://internal-app:9000/service
# Correct implementation
ProxyPass /service http://internal-app:9000/service
ProxyPassReverse /service http://public.example.com/service
Handling WebSocket Proxying:
ProxyPass /ws/ ws://backend-ws:8080/ws/
ProxyPassReverse /ws/ ws://public.example.com/ws/
For complex routing with multiple backends:
<Location /api/>
ProxyPass http://api-cluster/
ProxyPassReverse http://api.example.com/api/
ProxyPassReverseCookieDomain api-cluster api.example.com
ProxyPassReverseCookiePath / /api/
</Location>
Remember that while ProxyPassReverse
isn't always mandatory, omitting it frequently causes subtle bugs in production environments. The safest practice is to include it whenever using ProxyPass
.
While ProxyPass
handles the forwarding of requests to backend servers, ProxyPassReverse
modifies response headers from the backend to match the proxy server's domain. They serve complementary but distinct purposes in reverse proxy configurations.
When a backend server responds with headers containing its own domain (like Location or Content-Location), ProxyPassReverse
rewrites these to match the proxy's domain. Consider this common scenario:
# Without ProxyPassReverse
ProxyPass /app http://internal-server:8080/
# Backend responds with: Location: http://internal-server:8080/dashboard
# With ProxyPassReverse
ProxyPass /app http://internal-server:8080/
ProxyPassReverse /app http://internal-server:8080/
# Header becomes: Location: http://your-proxy.com/app/dashboard
You might skip ProxyPassReverse
when:
- Backend responses never include absolute URLs in headers
- You're proxying non-web protocols where header rewriting isn't needed
- Using WebSocket proxying (though some implementations still benefit from it)
For a REST API proxy setup:
ProxyPass /api/ http://api-backend:3000/
ProxyPassReverse /api/ http://api-backend:3000/
ProxyPassReverseCookieDomain api-backend your-proxy.com
ProxyPassReverseCookiePath /api/ /
For a complex multi-path configuration:
# Main application
ProxyPass / http://app-server:8080/
ProxyPassReverse / http://app-server:8080/
# Admin interface
ProxyPass /admin/ http://admin-server:9090/admin/
ProxyPassReverse /admin/ http://admin-server:9090/admin/
# Static assets
ProxyPass /static/ !
Alias /static/ /path/to/static/files/
To debug header rewriting problems:
# Enable logging in httpd.conf
LogLevel debug
CustomLog logs/proxy_debug.log "%h %l %u %t \"%r\" %>s %b %{Location}o %{Content-Location}o"
Common symptoms needing ProxyPassReverse:
- Redirect loops where the client tries accessing backend URLs directly
- Mixed content warnings when backend references its own domain
- Broken links in AJAX responses or Single Page Applications