104 lines
4.3 KiB
Markdown
104 lines
4.3 KiB
Markdown
---
|
|
title: "Apache mod_alias Takes Priority Over mod_proxy"
|
|
aliases: [apache-alias-proxy-conflict, mod-alias-mod-proxy, apache-proxy-silent-failure]
|
|
tags: [apache, proxy, mod_alias, gotcha, optical-dev, deployment]
|
|
sources:
|
|
- "daily/2026-04-30.md"
|
|
created: 2026-04-30
|
|
updated: 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
|
|
|
|
```apache
|
|
# 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
|
|
|
|
```apache
|
|
# 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
|
|
|
|
```apache
|
|
# 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:
|
|
|
|
```apache
|
|
# 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.
|
|
|
|
## Related Concepts
|
|
|
|
- [[wiki/concepts/apache-proxypass-include-files-ignored]] — related Apache silent failure: ProxyPass in Include fragments ignored
|
|
- [[wiki/architecture/optical-dev-server-deploy]] — optical-dev Apache vhost pattern, Alias and ProxyPass layout
|
|
|
|
## Sources
|
|
|
|
- [[daily/2026-04-30.md]] — Sessions 15:45 and 15:59, mod_alias winning over mod_proxy for video-accessibility
|