feat(deploy): 增加受控更新与环境配置迁移
This commit is contained in:
@@ -15,6 +15,10 @@ if [[ "${1:-}" =~ ^(-h|--help)$ ]]; then
|
||||
echo " UPDATE_SKIP_REPO_UPDATE=true|false"
|
||||
echo " true 等同 UPDATE_MODE=image"
|
||||
echo " false 等同 UPDATE_MODE=full"
|
||||
echo " UPDATE_HEALTH_TIMEOUT_SECONDS=秒数"
|
||||
echo " 等待核心服务恢复可用的最长时间,默认 300 秒"
|
||||
echo ""
|
||||
echo "仓库更新后会自动执行 scripts/update-env.d 中的幂等环境配置迁移。"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -100,8 +104,9 @@ if [ "$SKIP_REPO_UPDATE" = false ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📥 正在执行 git pull..."
|
||||
if git pull; then
|
||||
before_revision="$(git rev-parse HEAD)"
|
||||
echo "📥 正在执行 git pull --ff-only..."
|
||||
if git pull --ff-only; then
|
||||
echo "✅ 仓库已更新到最新版本"
|
||||
else
|
||||
echo "❌ git pull 失败,请检查网络或远程仓库配置"
|
||||
@@ -116,6 +121,12 @@ if [ "$SKIP_REPO_UPDATE" = false ]; then
|
||||
[ ! -f .env.ASG ] && [ -f .env.ASG.sample ] && cp .env.ASG.sample .env.ASG && echo " ✓ .env.ASG"
|
||||
[ ! -f .env.AMS ] && [ -f .env.AMS.sample ] && cp .env.AMS.sample .env.AMS && echo " ✓ .env.AMS"
|
||||
|
||||
after_revision="$(git rev-parse HEAD)"
|
||||
if [ "$before_revision" != "$after_revision" ] && [ "${EASYAI_UPDATE_REEXECUTED:-0}" != "1" ]; then
|
||||
echo "🔄 检测到部署仓库已更新,切换到新版更新脚本继续执行..."
|
||||
exec env EASYAI_UPDATE_REEXECUTED=1 UPDATE_SKIP_REPO_UPDATE=true "$SCRIPT_DIR/update.sh"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
else
|
||||
echo "⏭️ 跳过仓库更新,仅更新镜像并重启"
|
||||
@@ -129,6 +140,10 @@ if [ ! -f .env ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 每次更新都执行版本化、幂等的环境配置迁移。迁移只补缺失/空值或必要的列表项,
|
||||
# 不覆盖用户已经配置的非空值。后续新增必需配置时只需增加编号迁移文件。
|
||||
bash ./scripts/apply-update-env-migrations.sh .env "$SCRIPT_DIR"
|
||||
|
||||
# 老部署缺少绑定配置时,根据现有公开 API 地址迁移:域名/本机保持回环,IP 直连保持可用。
|
||||
# shellcheck source=scripts/init-server-http-bind-ip.sh
|
||||
. ./scripts/init-server-http-bind-ip.sh
|
||||
@@ -162,7 +177,7 @@ else
|
||||
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
|
||||
|
||||
echo "🔑 添加 Docker GPG 密钥..."
|
||||
curl -fsSL https://mirrors.nwafu.edu.cn生成注释ker-ce/linux/ubuntu/gpg | sudo apt-key add -
|
||||
curl -fsSL https://mirrors.nwafu.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
|
||||
|
||||
echo "🌍 添加 Docker 源..."
|
||||
sudo add-apt-repository -y "deb [arch=amd64] https://mirrors.nwafu.edu.cn生成注释ker-ce/linux/ubuntu/ $(lsb_release -cs) stable"
|
||||
@@ -203,9 +218,65 @@ $DOCKER_COMPOSE_CMD version
|
||||
|
||||
echo "🎉 Docker 和 Docker Compose 已就绪!"
|
||||
|
||||
wait_for_core_services() {
|
||||
local timeout_seconds="${UPDATE_HEALTH_TIMEOUT_SECONDS:-300}"
|
||||
local deadline=$((SECONDS + timeout_seconds))
|
||||
local services=(easyai-server ws-gateway easyai-web)
|
||||
local service container_id state running health all_ready
|
||||
|
||||
if ! [[ "$timeout_seconds" =~ ^[1-9][0-9]*$ ]]; then
|
||||
echo "❌ UPDATE_HEALTH_TIMEOUT_SECONDS 必须是正整数,当前为: $timeout_seconds"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "⏳ 正在等待核心服务恢复可用(最长 ${timeout_seconds} 秒)..."
|
||||
while (( SECONDS < deadline )); do
|
||||
all_ready=true
|
||||
for service in "${services[@]}"; do
|
||||
container_id="$(sudo $DOCKER_COMPOSE_CMD ps -q "$service" 2>/dev/null || true)"
|
||||
if [ -z "$container_id" ]; then
|
||||
all_ready=false
|
||||
continue
|
||||
fi
|
||||
|
||||
state="$(sudo docker inspect --format '{{.State.Running}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' "$container_id" 2>/dev/null || true)"
|
||||
running="${state%%|*}"
|
||||
health="${state#*|}"
|
||||
if [ "$running" != "true" ] || { [ "$health" != "none" ] && [ "$health" != "healthy" ]; }; then
|
||||
all_ready=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$all_ready" = true ]; then
|
||||
echo "✅ 核心服务已恢复可用"
|
||||
return 0
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
echo "❌ 更新后核心服务未在 ${timeout_seconds} 秒内恢复可用"
|
||||
echo " 当前状态:"
|
||||
sudo $DOCKER_COMPOSE_CMD ps easyai-server ws-gateway easyai-web || true
|
||||
echo " 请运行 '$DOCKER_COMPOSE_CMD logs --tail=100 easyai-server ws-gateway easyai-web' 查看原因"
|
||||
return 1
|
||||
}
|
||||
|
||||
# 旧 Redis 若仍把 AOF/RDB 留在容器写层,直接 up 会丢失数据。
|
||||
sudo ./scripts/check-redis-persistence.sh
|
||||
|
||||
echo "🚀 重新启动EasyAI"
|
||||
sudo $DOCKER_COMPOSE_CMD pull && sudo $DOCKER_COMPOSE_CMD up -d
|
||||
echo "🎉EasyAI应用更新成功"
|
||||
echo "📦 当前磁盘空间:"
|
||||
df -h "$SCRIPT_DIR" | tail -n 1
|
||||
if ! sudo $DOCKER_COMPOSE_CMD pull; then
|
||||
echo "❌ 镜像拉取失败,EasyAI 未被标记为更新成功"
|
||||
echo " 请检查网络、镜像仓库权限和服务器磁盘空间后重试"
|
||||
exit 1
|
||||
fi
|
||||
if ! sudo $DOCKER_COMPOSE_CMD up -d; then
|
||||
echo "❌ 容器启动失败,EasyAI 未被标记为更新成功"
|
||||
exit 1
|
||||
fi
|
||||
if ! wait_for_core_services; then
|
||||
exit 1
|
||||
fi
|
||||
echo "🎉 EasyAI 应用更新成功"
|
||||
|
||||
Reference in New Issue
Block a user