obsidian/wiki/concepts/apache-mod-alias-proxy-priority.md
2026-05-06 21:05:03 +01:00

4.3 KiB

title aliases tags sources created updated
Apache mod_alias Takes Priority Over mod_proxy
apache-alias-proxy-conflict
mod-alias-mod-proxy
apache-proxy-silent-failure
apache
proxy
mod_alias
gotcha
optical-dev
deployment
daily/2026-04-30.md
2026-04-30 2026-05-06

Apache mod_alias Takes Priority Over mod_proxy

When an Alias /path /var/www/html/path directive and a ProxyPass /path/ directive target the same URL prefix, Apache's mod_alias hooks earlier in the request processing chain than mod_proxy. If the physical directory exists on disk, Alias wins silently — API requests under that prefix are never proxied.

Key Points

  • mod_alias runs at the URL translation phase — earlier than mod_proxy in Apache's hook chain
  • When a physical directory matching the Alias exists on disk, Alias wins for ALL requests under that prefix
  • ProxyPass /path/api/ never fires — silent failure, no Apache error, no 502
  • Fix option 1: use RewriteRule [P,L] for API paths, placed BEFORE the Alias directive
  • Fix option 2: serve static files from a different path than the proxy prefix
  • This only affects cases where the static directory actually exists — if the directory is absent, Alias is a no-op and ProxyPass works

Details

The Conflict Pattern

# Static files under /video-accessibility/
Alias /video-accessibility /var/www/html/video-accessibility

# API proxy under same prefix — NEVER FIRES when directory exists
ProxyPass /video-accessibility/api/ http://127.0.0.1:8042/api/
ProxyPassReverse /video-accessibility/api/ http://127.0.0.1:8042/api/

Apache's processing order for this config:

  1. URL translation phase: Alias runs → matches /video-accessibility/* → resolves to filesystem path
  2. mod_proxy phase: never reached for requests under /video-accessibility/

Fix 1: RewriteRule with [P,L] for API Paths

# Place BEFORE the Alias directive
RewriteEngine On
RewriteRule ^/video-accessibility/api/(.*)$ http://127.0.0.1:8042/api/$1 [P,L]

# Static files — now only catches non-API paths
Alias /video-accessibility /var/www/html/video-accessibility

The [P] flag (proxy) and [L] flag (last rule, stop processing) together replicate ProxyPass behaviour. RewriteRule runs at the fixups stage and can override alias translation when declared first.

Fix 2: Separate Paths

# Static files at /video-accessibility/ (Alias)
Alias /video-accessibility /var/www/html/video-accessibility

# API at a completely different path prefix
ProxyPass /video-accessibility-api/ http://127.0.0.1:8042/api/

This avoids the conflict entirely but requires updating frontend API call paths.

Diagnosis

If ProxyPass rules appear correct but API calls return static HTML (or 404s from the filesystem):

  1. Check if an Alias directive covers the same prefix
  2. Verify the physical directory exists: ls /var/www/html/<path>
  3. If both exist, you have this conflict

Fix 3: ProxyPassMatch with Explicit Prefix Stripping

When using a FastAPI app with root_path behind a conflicting Alias, ProxyPassMatch can strip the prefix manually:

# Static files served by Alias
Alias /cc-dashboard /var/www/html/cc-dashboard

# API proxy: capture everything AFTER /cc-dashboard/ and forward without prefix
# FastAPI receives /api/... not /cc-dashboard/api/...
ProxyPassMatch ^/cc-dashboard/api/(.*)$ http://127.0.0.1:8001/api/$1
ProxyPassMatch ^/cc-dashboard/healthz$ http://127.0.0.1:8001/healthz

# RewriteRule [P,L] alternative (same effect)
RewriteEngine On
RewriteRule ^/cc-dashboard/api/(.*)$ http://127.0.0.1:8001/api/$1 [P,L]

This pattern is required when:

  1. An Alias covers the same prefix (so simple ProxyPass never fires)
  2. The FastAPI app is configured with root_path="/cc-dashboard" (routes registered without prefix)

See wiki/concepts/fastapi-root-path-route-stripping for why FastAPI routes must NOT include the prefix.

Sources

  • daily/2026-04-30.md — Sessions 15:45 and 15:59, mod_alias winning over mod_proxy for video-accessibility