CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Nginx 反向代理入门/课时/静态资源
RawBlame
课时目录12 节

Nginx 反向代理入门

  1. 01Nginx 是什么
  2. 02安装与 nginx -t
  3. 03配置文件结构
  4. 04静态资源
  5. 05反向代理基础
  6. 06双 upstream 架构
  7. 07HTTPS 与证书
  8. 08安全响应头
  9. 09缓存与性能
  10. 10负载均衡
  11. 11Nginx 与 Ingress
  12. 12综合练习

静态资源

root、index、try_files、gzip。

25 分钟

静态资源

这一课你将能做到

  1. 用 root、index、try_files 托管一个前端构建产物(SPA),并解释 URI 如何拼到磁盘路径
  2. 说明 CodeRoadMap 主站为何反代 Next、admin 为何 Nginx 静态,对照 prod.conf.example
  3. 为带 hash 的 js/css/图片写 expires,并区分「壳 HTML」与「不可变静态」的缓存策略

为什么要学

Nginx 发静态文件极快:零应用进程、内核 sendfile、少拷贝。管理后台、落地页、文档站常常 构建完直接丢给 Nginx。
CodeRoadMap 主站是 Next(SSR/RSC),不适合整站 root;但 admin.coderoadmap.cn 正是 root + try_files 的经典 SPA 托管。
把「静态托管」与「反代动态」分清,才不会把 Next 的 _next/static 误当成必须由 Nginx 读盘,或给 index.html 乱加一年缓存导致发版后用户卡旧壳。

先建立图像

请求 URI: /assets/app.abc123.js
root:     /var/www/coderoadmap-admin/dist
磁盘文件: /var/www/coderoadmap-admin/dist + /assets/app.abc123.js

SPA 深链: /users/42
try_files: 文件?→ 目录?→ 回退 /index.html(前端路由接手)
站点入口方式原因
wwwproxy_pass → :3000SSR/RSC、动态路由、鉴权页
adminroot + try_filesVite 等静态构建,无 Node 常驻亦可

人话:静态像「自助取件柜」——柜子直接给你文件;动态反代像「柜台打电话到后厨」——后厨(Next/Java)现做。

跟着做

步骤 1:对照官方 root / index

阅读 Serving Static Content 中静态部分,记下:root 指定目录,URI 拼在后面;index 决定目录默认页。

步骤 2:读 prod 里 admin 块

打开 deploy/nginx/prod.conf.example 的 admin server:

server {
    listen 443 ssl http2;
    server_name admin.coderoadmap.cn;

    # 构建产物目录(部署时把 dist 同步到此)
    root /var/www/coderoadmap-admin/dist;
    index index.html;

    location /api/ {
        # 管理端 API 仍进 Spring Boot
        proxy_pass http://coderoadmap_backend/;
        # … headers …
    }

    location / {
        # SPA:真实文件优先,否则回退前端路由
        try_files $uri $uri/ /index.html;
    }
}

在笔记写两句:

  1. 静态资源与 /api/ 可共存于同一 server
  • 页面路由不进 Java,接口才进 Java
  • 步骤 3:本机最小静态实验(可选)

    sudo mkdir -p /var/www/lab-static
    echo '<h1>lab</h1>' | sudo tee /var/www/lab-static/index.html
    

    片段:

    server {
        listen 8088;
        server_name localhost;
        root /var/www/lab-static;
        index index.html;
    
        location / {
            try_files $uri $uri/ =404;
        }
    }
    

    nginx -t → reload → curl -i http://127.0.0.1:8088/。应看到 HTML。
    再访问不存在路径,应 404(本实验用 =404;SPA 则改 /index.html)。

    步骤 4:理解 try_files 对 SPA 的意义

    前端路由 /settings/profile 在服务器上通常 没有同名文件。没有 try_files … /index.html 时 Nginx 返回 404;有则返回壳,由浏览器 JS 路由。
    接口路径必须另写 location /api/,否则会被回退成 index.html(内容类型错误、前端误解析)。

    步骤 5:gzip 与类型(http 级)

    http {
        gzip on;
        gzip_vary on;
        gzip_min_length 1024;
        # 只压文本类;图片/woff2 往往已压缩
        gzip_types text/plain text/css application/json
                   application/javascript text/xml application/xml;
    }
    

    应看到:压缩省带宽;CPU 换体积。过小的文件不必压(gzip_min_length)。

    步骤 6:缓存头分层

    # 带 content hash 的静态:可长缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|svg|woff2)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }
    
    # HTML 壳:避免用户卡在旧 index
    location = /index.html {
        add_header Cache-Control "no-cache";
    }
    

    主站若反代 Next,长缓存常打在 /_next/static/(见缓存课);本课先在 纯静态 admin 建立正确直觉。

    讲清楚要点

    1. 因为 root 与 URI 拼接成磁盘路径,所以 root 应指向构建产物根(如 dist)——不要指到含源码的上层乱目录。
    2. 因为 SPA 深链没有真实文件,所以需要 try_files 回退 index.html——否则刷新子路由 404。
    3. 因为 /api/ 也是路径,所以静态站仍要单独 location 反代 API——避免 API 被当成前端路由。
    4. 因为主站依赖 Next 运行时,所以 www 用 proxy_pass 而不是整站 root——RSC/SSR 不是纯静态。
    5. 因为 hash 文件名可变,所以 js/css 可长缓存;HTML 应短缓存或 no-cache——发版体验取决于壳是否更新。
    6. 因为图片与字体多已压缩,所以 gzip 聚焦文本类型——避免重复压缩浪费 CPU。
    7. 因为官方静态模型简单明确,所以排错优先看:文件是否存在、权限、root 是否指对——再查 try_files 顺序。

    你可能会懵的地方

    • root 和 alias 有什么差别?
      root:location URI 保留并拼到 root 后。alias:用 alias 路径替换 location 前缀。入门先精通 root;用 alias 时务必注意尾斜杠配对。

    • Next 的 public/ 还要不要 Nginx root?
      主站反代时,public/ 由 Next 自己提供。Nginx 不必再 mirror 一份,除非你做特殊边缘缓存。

    • try_files $uri $uri/ /index.html 最后一项为什么是 URI?
      最后参数是 内部重定向的 URI(再走一遍 location),不是随意磁盘路径写法。细节见官方 try_files。

    • 静态站还要 HTTPS 吗?
      要。admin 同样在 443 终止 TLS;安全头往往更严(见 ngx-headers)。

    错法对照

    错法问题正解
    主站整站 root 指到 Next 项目目录SSR 失效、源码暴露风险www 反代 :3000
    SPA 无 try_files刷新子路由 404try_files $uri $uri/ /index.html
    给所有响应 expires 365dHTML 壳卡住旧版本hash 资源长缓存;HTML no-cache
    API 与静态共用一个宽 location/api 返回 index.html独立 location /api/
    root 指到仓库而非 dist404 或发错文件部署同步构建产物目录

    自测三问

    1. URI /logo.png 在 root /var/www/app/dist 时对应哪个磁盘路径?
    2. 为何 admin 需要 try_files,而 /api/ 不能靠它回退?
    3. 为什么带 hash 的 js 可以 immutable,而 index.html 通常不行?

    小结一句话

    静态 = root + index + try_files;CodeRoadMap 主站动态反代,admin 静态托管并共用 /api 上游。

    官方延伸

    • Serving Static Content
    • ngx_http_core_module — try_files
    加载本节练习…
    ← 上一课配置文件结构下一课 →反向代理基础