Shell 自动化部署脚本:git pull + pnpm build + cp

一个用于静态站点(如 Astro / Next.js)的最小化自动化部署脚本,适合 VPS 手动触发或配合 webhook 使用。

脚本

#!/bin/bash
set -e

cd /opt/black-no-dark
git pull
pnpm build
cp -rf /opt/black-no-dark/dist/* /www/wwwroot/www.example.com/

echo "更新成功!"

各步骤说明

set -e:任何命令返回非零退出码时立即终止脚本,防止后续步骤在错误状态下继续执行。

git pull:拉取远程最新代码。若本地有未提交的修改会冲突报错,此时 set -e 会阻止继续构建。

pnpm build:构建静态产物到 dist/ 目录。构建失败(TS 错误、配置错误等)同样会终止。

cp -rf dist/* /web-root/:将新产物覆盖到 Web 服务器根目录。-r 递归,-f 强制覆盖。

使用方式

# 赋予执行权限(只需一次)
chmod +x /opt/deploy.sh

# 手动触发
/opt/deploy.sh

# 或配合 webhook(如 github-webhook-handler)自动触发

常见问题

git pull 报 “not a git repository”:脚本中的 cd 路径写错,或目录没有 git init / git clone

pnpm: command not found:部署环境没有安装 pnpm,或 PATH 不包含 pnpm 路径。解决:

# 用绝对路径
/root/.local/share/pnpm/pnpm build

# 或在脚本顶部加
export PATH="/root/.local/share/pnpm:$PATH"

cp 覆盖时网站短暂不可用:对于零停机要求,可以先 cp 到临时目录,再 mv 替换:

cp -rf dist/* /tmp/dist-new/
rsync -a --delete /tmp/dist-new/ /www/wwwroot/www.example.com/

rsync 只同步差异文件,比整体 cp 更快,中断窗口更短。

扩展:加上日志和通知

#!/bin/bash
set -e

LOG=/var/log/deploy.log
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始部署" >> $LOG

cd /opt/black-no-dark
git pull >> $LOG 2>&1
pnpm build >> $LOG 2>&1
cp -rf dist/* /www/wwwroot/www.example.com/

echo "[$(date '+%Y-%m-%d %H:%M:%S')] 部署成功" >> $LOG

将 stdout / stderr 都重定向到日志文件,方便事后排查。