deploy.sh 部署脚本:健康检查 + 自动回滚

背景 上一篇配置了 GitHub Actions,push 后自动 SSH 到服务器执行 deploy.sh。

但最初的脚本只有三行:

bash 复制代码
cd /home/ubuntu/app
git pull
docker compose up -d --build

问题:如果新代码有 bug,容器起不来------网站直接挂,而且不会自动退回旧版本。

原因 部署脚本只做了"往前",没做"往后"。

一个能用的部署脚本,至少要包5个环节:

1. 部署脚本的完整环节

一个可靠的部署脚本,至少要包含以下五个环节:

环节 作用
记录当前版本 出错时知道回滚到哪
拉取新代码 更新到最新
构建+启动 应用新版本
健康检查 验证服务真的能用了
失败回滚 健康检查不过,退回旧版本

完整脚本

bash 复制代码
#!/bin/bash
set -euo pipefail

PROJECT_DIR="/home/ubuntu/app"
HEALTH_URL="http://127.0.0.1:8081/api/health"

cd "$PROJECT_DIR"

echo "🚀 开始部署 - $(date '+%F %T')"

# 1. 记录当前版本
LAST_GOOD=$(git rev-parse HEAD)
echo "📌 当前版本: ${LAST_GOOD:0:8}"

# 2. 回滚函数
rollback() {
    echo "⚠️ 部署失败,回滚到 ${LAST_GOOD:0:8}"
    git reset --hard "$LAST_GOOD"
    docker compose up -d --build
    exit 1
}
trap rollback ERR

# 3. 拉取最新代码
git fetch --all
git reset --hard origin/main
NEW_COMMIT=$(git rev-parse --short HEAD)
echo "📌 目标版本: $NEW_COMMIT"

# 4. 构建 + 启动
docker compose up -d --build

# 5. 健康检查(重试 5 次)
for i in $(seq 1 5); do
    sleep 3
    if curl -fsS "$HEALTH_URL" > /dev/null 2>&1; then
        echo "✅ 健康检查通过(第 $i 次)"
        exit 0
    fi
    echo "  第 $i 次失败,等待 3 秒..."
done

# 6. 健康检查失败,回滚
echo "❌ 健康检查 5 次全失败"
rollback

关键点解读 set -euo pipefail ------ 脚本的"安全模式":

-e:任何命令失败立刻退出

-u:使用未定义变量报错

-o pipefail:管道中任何一环失败都算失败

没有这三条,脚本会"假装成功"------中间命令挂了它还继续往下跑。

trap rollback ERR ------ 捕获任何错误触发回滚:

bash 复制代码
trap rollback ERR

之后脚本里任何一条命令失败,都会自动调 rollback()。

健康检查重试 5 次 ------ 不要只检查一次:

bash 复制代码
for i in $(seq 1 5); do
    sleep 3
    if curl -fsS "$HEALTH_URL" > /dev/null 2>&1; then
        echo "✅ 通过"
        exit 0
    fi
done

容器启动后需要几秒钟才能响应,给 15 秒的窗口,比只检查一次稳得多。

三个坑 坑 1:没加 set -e,脚本"假装成功"

比如 docker compose up -d --build 失败了,脚本不会中断,还会继续执行健康检查、输出"部署成功"。这种脚本比没有更危险------你以为部署成功了,其实没有。

坑 2:健康检查只跑一次

curl 一次失败就回滚,太激进。容器启动有延迟,要重试几次。把 5 次 × 3 秒的窗口当成标配。

坑 3:回滚用的是 git reset --hard

这会把服务器上的代码退回旧版本。但如果下一个 push 又拉最新代码,坏代码又回来了。真正的回滚应该是 git revert 后 push 到 GitHub------但那需要 deploy key 有写权限。

简化版:目前 reset --hard 够用。等有真实用户了,再上"revert + push"方案。

相关推荐
姜鱼问生1 小时前
GitHub Actions CI/CD 从零搭建:push 后 60 秒自动上线
云计算·github
其实防守也摸鱼1 小时前
渗透测试学习计划(全栈综合 · 零基础进阶)
android·数据库·学习·安全·oracle·自动化·学习方法
Black蜡笔小新1 小时前
EasyCVR从“人盯人”到“AI盯岗”:可视化大屏+智能告警,岗位管理一屏掌控
网络·安全·easycvr
王潇9831 小时前
零依赖、单文件:一套自创的分析框架,和它的三个应用站点
github
阿俊在Coding2 小时前
从 0 实现最小 Coding Agent:读懂 Pi 生产级 Agent 的骨架
github
kakakahahahaha2 小时前
电脑显示器无信号排查:HDMI/DP接口、独立显卡、内存与安全模式
windows·安全·电脑·笔记本电脑·内容运营·软件需求
开开心心就好2 小时前
二维码批量生成导出工具,离线可用完全免费
java·前端·人工智能·智能手机·github·excel·visual studio
wflynn2 小时前
GitHub 日榜趋势速报 | 2026-10-03
开源·github
本地化文档2 小时前
pygmt-docs-l10n
python·github·gitcode·sphinx·pygmt·gmt·crowdin