The ProxyPassReverse
directive serves as a critical component in Apache's reverse proxy configuration. When your backend server issues HTTP redirects (3xx responses), this directive modifies the Location
, Content-Location
, and URI
headers in the response to maintain the reverse proxy facade.
Consider this common scenario without ProxyPassReverse
:
# Backend server responds with:
HTTP/1.1 302 Found
Location: http://backend.internal/app/newpath
Without modification, the client would receive this redirect and attempt to connect directly to backend.internal
, bypassing your proxy entirely.
Here's a complete reverse proxy setup with ProxyPassReverse
:
<VirtualHost *:80>
ServerName proxy.example.com
ProxyPass /app/ http://backend.internal:8080/
ProxyPassReverse /app/ http://backend.internal:8080/
# Additional reverse proxy settings
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "http"
</VirtualHost>
For complex environments with multiple backend paths:
ProxyPass /service1/ http://backend1.internal:8000/
ProxyPassReverse /service1/ http://backend1.internal:8000/
ProxyPass /service2/ http://backend2.internal:9000/
ProxyPassReverse /service2/ http://backend2.internal:9000/
Problem: Redirects still bypass the proxy
Solution: Ensure the ProxyPassReverse
path matches exactly with ProxyPass
Problem: HTTPS redirects break
Solution: Add protocol-aware configuration:
ProxyPassReverse / https://backend.internal/
ProxyPassReverse / http://backend.internal/
For complete URL rewriting in HTML content:
ProxyHTMLEnable On
ProxyHTMLURLMap http://backend.internal/ /
Enable detailed logging to troubleshoot redirect issues:
LogLevel debug
CustomLog ${APACHE_LOG_DIR}/proxy.log "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\""
When implementing reverse proxy configurations in Apache, backend servers often issue HTTP redirects (301/302 responses) containing backend-specific URLs in Location headers. Without proper handling, these redirects would expose internal server structures and potentially bypass the proxy entirely.
# Problematic scenario without ProxyPassReverse
ProxyPass "/app/" "http://backend-server:8080/internal-app/"
If the backend issues a redirect to "/internal-app/dashboard", clients receive this raw internal URL, breaking the reverse proxy abstraction.
The directive modifies three response headers:
- Location (HTTP redirects)
- Content-Location (resource identifiers)
- URI (rarely used header)
It performs string substitution based on the same path mapping rules as ProxyPass:
# Basic configuration example
ProxyPass "/public/app/" "http://internal-server:8000/"
ProxyPassReverse "/public/app/" "http://internal-server:8000/"
Simple Single-Server Setup
<VirtualHost *:443>
ServerName public.example.com
ProxyPass "/api/" "http://10.0.1.42:3000/"
ProxyPassReverse "/api/" "http://10.0.1.42:3000/"
# Required for WebSocket support
ProxyPass "/ws/" "ws://10.0.1.42:3001/"
ProxyPassReverse "/ws/" "ws://10.0.1.42:3001/"
</VirtualHost>
Complex Path Rewriting Scenario
# When backend paths differ from frontend
ProxyPass "/customer-portal/v2/" "http://backend/v3/portal/"
ProxyPassReverse "/customer-portal/v2/" "http://backend/v3/portal/"
# Additional configuration for cookies if needed
ProxyPassReverseCookiePath "/v3/portal/" "/customer-portal/v2/"
Multiple Backend Servers
For load-balanced setups, ensure ProxyPassReverse matches all possible backend URLs:
<Proxy balancer://app-cluster>
BalancerMember http://backend1:8080
BalancerMember http://backend2:8080
</Proxy>
ProxyPass "/app/" "balancer://app-cluster/"
ProxyPassReverse "/app/" "http://backend1:8080/"
ProxyPassReverse "/app/" "http://backend2:8080/"
SSL Termination Cases
When the proxy handles HTTPS but communicates with backends via HTTP:
ProxyPass "/" "http://backend/"
ProxyPassReverse "/" "http://backend/"
ProxyPassReverse "/" "https://public-domain.com/"
Using Regular Expressions
# Apache 2.4+ syntax
ProxyPassMatch "^/(.*)-service/(.*)" "http://backend/$1/$2"
ProxyPassReverse "/user-service/" "http://backend/user/"
ProxyPassReverse "/order-service/" "http://backend/order/"
Combining with Other Modules
For complete URL rewriting including HTML content:
# Requires mod_proxy_html
ProxyHTMLEnable On
ProxyHTMLURLMap http://backend/ /
Diagnostic steps:
- Enable mod_headers to inspect raw responses:
Header always set X-Proxy-Debug "enabled"
- Check Apache error logs with LogLevel debug
- Use curl with -v flag to examine headers:
curl -v https://proxy/app/redirect-endpoint