DocumentRoot 应指向静态资源可被 HTTP 直接访问的物理入口,如前端 build 后的 dist/ 或 public/ 目录,而非源码根目录;需与应用路径、URL 和反向代理规则对齐,配合 ProxyPassMatch 实现动静分离。

Apache 的 DocumentRoot 是动静分离的起点,不是终点。配得对,静态资源能直出、快加载、少转发;配错了,路径多一层、404频发、缓存失效——关键在于它和应用部署结构、URL 路径、反向代理规则三者必须对齐。
明确 DocumentRoot 应该指向哪一级
它不该指向项目源码根目录(如 /var/www/html/myapp),而应指向**静态资源实际可被 HTTP 直接访问的物理入口**。常见合理位置有:
-
前端构建产物目录:如 Vue/React 项目 build 后的
dist/或 Laravel 的public/,设为DocumentRoot /var/www/html/myapp/public -
纯静态资源根目录:若已做路径隔离(如所有静态走
/static/),可设DocumentRoot /var/www/static,再用Alias或ProxyPassMatch补充其他路径 -
不设为应用根,而是交由反向代理接管:当 Apache 仅作负载均衡器时,
DocumentRoot可设为一个空或最小化目录(如/var/www/empty),所有请求靠ProxyPass分流
避免 DocumentRoot 与应用 base URL 冲突
如果后端框架生成的资源链接是 /css/app.css,但 DocumentRoot 指向的是 /var/www/html/myapp,而真实文件在 /var/www/html/myapp/public/css/,浏览器就会 404。解决方式二选一:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 改 Apache:
DocumentRoot /var/www/html/myapp/public,并确保对应<Directory>开放读取权限 - 改应用:
APP_URL=https://example.com/myapp(Laravel)、publicPath: '/myapp/'(Vue CLI),让所有资源路径带上前缀 - 两者都不动?加
Alias /myapp /var/www/html/myapp/public,再配合<Location /myapp>单独授权
结合 ProxyPass 实现精准动静分流
DocumentRoot 只管“谁来响应根路径”,真正的动静拆分靠规则拦截。推荐用 ProxyPassMatch 提前匹配静态扩展名,绕过应用服务器:
- 在虚拟主机配置中加入:
<!-- 匹配常见静态后缀,直接转给静态节点 -->
ProxyPassMatch ^/(.*\.(jpg|jpeg|png|gif|css|js|woff2|svg|ico|ttf))$ http://static-servers/$1
<!-- 或按路径隔离,更清晰 -->
ProxyPass /static/ http://static-servers/static/
ProxyPass /uploads/ http://static-servers/uploads/
<!-- 动态路径交给后端 -->
ProxyPass /api/ http://app-servers/api/
ProxyPass /admin/ http://app-servers/admin/
- 务必加
ProxyPreserveHost off,防止 Host 头透传导致静态服务器虚拟主机判断错误 - 静态节点上禁用 PHP 等动态模块,只启用
mod_expires、mod_headers、mod_deflate
验证与调优要点
配完别急着重启,先检查三件事:
- 运行
apachectl -t -D DUMP_VHOSTS,确认生效的DocumentRoot和ProxyPass规则顺序是否符合预期 - 打开浏览器开发者工具 → Network 标签,看
css/js请求状态码是不是 200,Response Headers 里有没有Cache-Control和Expires - 用
curl -I https://example.com/css/app.css检查返回头,确认没被后端拦截(比如 Tomcat 返回了 404 或 302)

















