在一个next.js的前端项目中遇到了奇怪的问题:
直连 Next.js(
:3000)能正常显示新内容,但经过 Nginx 反向代理(:80)的站点却显示老页面。
:3000 是直连 Next.js 容器,不经过 Nginx:80(不带端口)才是经过 Nginx 反向代理的入口结论:
直接访问
:3000端口能看到最新代码,但通过域名(走 Nginx 反代)访问却看到旧页面——因为 Nginx 把旧页面缓存了 1 年没刷新。
一、问题现象
| 访问方式 | 表现 |
|---------|------|
| `http://www.cnzhanzhang.com:3000` | 导航栏正常,显示"HOMExxx"(最新代码) |
| `http://www.cnzhanzhang.com`(80端口) | 导航栏不显示最新内容,显示旧版页面 |
### 二、排查过程
**第一层:排除环境变量问题**
- 网上建议加 `NEXT_PUBLIC_BASE_URL` 和 `NEXT_PUBLIC_APP_URL`
- 检查代码:整个项目**零引用**这两个变量 → ❌ 无效
**第二层:排除 Nginx `^~` 问题**
- 网上建议把 `location ^~ /` 改成 `location /`
- 检查实际配置:本来就是 `location /`,没有 `^~` → ❌ 无效
**第三层:检查 Nginx 配置**
- 确认 Nginx 是宝塔面板安装,配置路径 `/www/server/panel/vhost/nginx/`
- 配置本身正确,`proxy_pass http://127.0.0.1:3000` 指向正确
**第四层:检查 Docker 容器**
- 发现 `opc-website` 容器**没有挂载目录**,代码烘焙在镜像里
- 服务器源码目录 `/www/wwwroot/www.cnzhanzhang.com/` 里是旧代码(HOMExxx)
- 但容器里跑的镜像是新的 → 说明之前构建过但没重新 build
**第五层:检查缓存**
- 发现响应头:`Cache-Control: s-maxage=31536000`(缓存1年)
- `x-nextjs-cache: HIT` → Next.js 返回了缓存的旧页面
**第六层:最终定位**
- 把 `proxy_pass` 从 `127.0.0.1:3000` 改成 `www.cnzhanzhang.com:3000` 后正常
- 说明 **Nginx 的 proxy_cache 缓存了旧响应**
### 三、根因
**Next.js SSG 默认缓存 1 年** + **Nginx 默认开启 proxy_cache** = 旧页面被缓存,新代码更新后不生效。
### 四、解决方案
在 Nginx 配置里加两行:
```nginx
proxy_cache off;
add_header X-Proxy-Cache "BYPASS";
```
完整配置:
```nginx
server {
listen 80;
server_name cnzhanzhang.com www.cnzhanzhang.com;
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_no_cache 1;
proxy_buffering off;
proxy_cache off;
add_header X-Proxy-Cache "BYPASS";
}
}
```
### 五、经验教训