跳到主要内容

nginx软链接版本部署

前端部署软链接方式​

软链接相当于window的快捷模式

  • Nginx 的目录只保持为 /app/current
    • 但你只需要把它“指向”不同版本即可完成版本切换。
    • 新版本上线时 不需要修改 Nginx 配置
    • 不需要覆盖旧文件
    • 只需要修改软链接指向即可完成发布
    • /app/current → 指向一个真正的文件夹,比如:/releases/v1

用软链接切换版本​

  • Nginx 访问 /app/current,实际访问的是 /releases/v1
bash
ln -sfn /releases/v1 /app/current
参数作用
ln创建链接
-s创建软链接(symbolic link)
-f强制覆盖旧链接
-n保持链接行为,不跟随目录
  • 查看软链接
bash
ls -l /app

nginx配置​

bash
server {
listen 80;
server_name example.com;

root /app/current/dist;

location / {
try_files $uri $uri/ /index.html;
}
}

服务器需要定期清理旧版本问题​

  • 旧版本需要清理,但必须“安全清理”,不能随便删

原因:

  • dist 包越来越大(2–20MB)
  • 持续部署 1 年会积累几十甚至上百个版本
  • 会浪费磁盘空间

但不能全部删,只能删很旧的版本。 行业最佳实践:

公司推荐保留版本数
阿里3~5 个版本
字节最近 3 个版本
腾讯5~7 个版本(高流量应用)
谷歌 SPA2 个版本(有 SW 版本控制)

脚本删除​

bash
/app/releases/
v1
v2
v3
v4
v5
v6
  • 可以通过一个脚本,可以在服务器上自动清理旧版本,只保留最近 5 个版本
  • 按时间排序,获取需要删除的版本
bash
#!/bin/bash

# 版本发布目录
RELEASE_DIR="/app/releases"

# 保留最近几个版本
KEEP=5

# 进入版本目录
cd "$RELEASE_DIR" || exit 1

# 按时间排序,获取需要删除的版本
# tail -n +$((KEEP+1)) 表示保留前 KEEP 个,删除其余
OLD_VERSIONS=$(ls -dt */ | tail -n +$((KEEP+1)))

# 删除旧版本
for v in $OLD_VERSIONS; do
echo "Deleting old version: $v"
rm -rf "$v"
done

echo "Cleanup done. Remaining versions:"
ls -d */

问题总结​

  • 部署了新版本v2, 为什么用户“访问的是 v1”,却还能继续加载 v1,而 Nginx 明明已经指向 v2
  • 既然浏览器已经缓存了旧版本静态资源,为什么服务器还要保留旧版本?浏览器不能直接从本地缓存读吗

解释:

  • 浏览器缓存不是永远可用的,它随时可能失效或被清理。
    • 用户手动清除缓存
    • 浏览器自动清除(磁盘空间不足)
  • 因此浏览器缓存是“不可靠”的,保留服务器旧版本是最稳妥的
  • 单页面运行期间仍会请求新的文件,比如懒加载、按需加载,有些模块是通过懒加载,如果这个模块没有被缓存到,浏览器必须到服务器请求,而如果服务器旧版本已经删除,那么就会出现404报错情况
  • 浏览器缓存是基于 HTTP 响应头决定的,不是永久保存
    • 设置cache-contro的max-age设置过期时间
  • 当浏览器缓存不可用时,浏览器会去服务器重新请求