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 小时前
QUIC——HTTP/3 的唯一底层传输协议 及 0-RTT恢复
网络·网络协议·tcp/ip·安全·http
KCENN4 小时前
安全触边在电梯轿厢门防夹保护系统中的选型配置与长效维护要点
安全
feasibility.5 小时前
一物降一物?AI逆向没有终局:REA拆App,BLA设套,LASIK清场
人工智能·爬虫·github·逆向·skill·rea
小雉系统15 小时前
BcoreOS安全通信架构:FsSession 抗算法后门安全设计
算法·安全·架构
真好啊又活了一天1 天前
服务器和虚机配置IPV6
运维·服务器·github
Cosolar1 天前
极简简历:开源免费,希望帮助到更多求职者
开源·github·敏捷开发
Cosolar1 天前
极简智库:快速搭建你的开源项目教程阅读平台,让 docs/ 目录被更多人看见
java·架构·github
敢敢是只喵i1 天前
false不等于没填:一次 AI 接入业务系统的SDK的修复记录
github
一条Go1 天前
历史告警归档:为什么"删掉主库行"是最后一步
后端·架构·github