引言
在前端开发中,Vue.js 因其简洁和高效而广受欢迎。然而,部署 Vue 应用时,如何减少或消除部署过程中的停机时间,是一个值得关注的问题。本文将介绍一种无缝部署策略,通过结合 Nginx、FTP 和 Docker,实现 Vue 应用的平滑更新。
一、部署挑战
使用 FTP 部署 Vue 应用到 Nginx 服务器时,常见的问题包括:
- 部署期间用户无法访问应用。
- 直接上传文件耗时,尤其是当文件数量众多时。
二、解决方案概述
为了解决这些问题,我们可以采用以下策略:
- 保留旧版本文件:利用 Vue 构建时生成的包含哈希值的静态文件名。
- 分阶段上传:先压缩文件,再上传并解压。
- 监控和自动化部署:使用
inotifywait
和 Docker 实现实时监控和自动化部署。
三、部署流程详解
3.1 构建和上传
- 使用 Vue 的构建命令(如
npm run build
)生成静态文件。 - 将生成的
dist
目录压缩为dist.zip
。 - 通过 FTP 上传
dist.zip
到服务器。
3.2 自动化部署脚本
- 创建
deploy.sh
脚本,该脚本将监控特定目录,解压上传的dist.zip
,并清理旧文件。
3.3 脚本核心逻辑
#!/usr/bin/env bash
# 要监控的目录
WATCH_DIR="/html"
# 检查unzip是否存在
if ! command -v unzip &> /dev/null
then
echo "unzip could not be found"
exit 1
fi
# 无限循环,定期检查指定目录下是否有新的dist.zip文件
inotifywait -m -r -e close_write --format '%w %f' --include 'dist.zip' "$WATCH_DIR" | while read FILE_PATH FILE_NAME
do
echo "[$(date -Iseconds)]检测到文件上传:$FILE_PATH$FILE_NAME"
echo "[$(date -Iseconds)]开始解压..."
cd $FILE_PATH
# 尝试获取当前目录下index.html文件的修改时间
if [ -f "index.html" ]; then
lastModified=$(stat -c %Y "index.html")
# 计算24小时前的时间戳,并赋值给 timeLine
daysAgo=$((24 * 60 * 60))
timeLine=$((lastModified - daysAgo))
else
# 获取当前Unix时间戳
currentUnixTimestamp=$(date +%s)
# 计算365天前的Unix时间戳
daysAgo=$((365 * 24 * 60 * 60))
timeLine=$((currentUnixTimestamp - daysAgo))
fi
# 计算当前时间到时间线间的分钟数
time_minutes_ago=$(( ( $(date +%s) - timeLine) / 60 ))
# 将 timeLine 转换为可读的日期格式
timeLineReadable=$(date -d "@$timeLine" '+%Y-%m-%d %H:%M:%S')
# 第一次解压,排除index.html文件
echo "[$(date -Iseconds)]第一次解压,排除index.html..."
unzip -o "$FILE_NAME" -x 'index.html'
# 第二次解压,覆盖index.html文件
echo "[$(date -Iseconds)]第二次解压,覆盖index.html..."
unzip -o "$FILE_NAME" "index.html"
# 至此,解压完成
echo "[$(date -Iseconds)]解压完成。"
echo "[$(date -Iseconds)]删除目录及其子目录下修改时间早于 $timeLineReadable 的所有文件..."
#find . -type f -mmin +"$time_minutes_ago"
find . -type f -mmin +"$time_minutes_ago" -exec rm -v {} +
echo "[$(date -Iseconds)]清理空目录..."
find . -type d -empty -exec rmdir -v {} +
done
四、Docker 容器配置
使用 Docker 部署 frontend
服务,监控文件变化并执行 deploy.sh
脚本。
version: '3.8'
services:
frontend:
image: devodev/inotify
deploy:
replicas: 1
update_config:
order: stop-first
volumes:
- /mnt/nginx/html:/html
- /mnt/deploy/deploy.sh:/deploy.sh
environment:
INOTIFYWAIT_SCRIPT: '/deploy.sh'
五、无缝更新策略
- 保留旧版本:不删除旧版本的文件,直接上传新文件。
- 分阶段上传:压缩文件后上传,服务器端解压。
- 监控和自动化:使用
inotifywait
监控文件变化,自动化执行部署脚本。
六、清理旧文件
- 部署新版本后,清理旧文件以节省空间。
- 保留最近一次部署的文件,删除更早的版本。
七、结语
通过上述策略,我们可以实现 Vue 应用的无缝部署,减少部署过程中对用户的影响。这种方法不仅适用于 Vue,也可以扩展到其他前端框架和应用。