Files
codex-app-server/deploy/rollback.sh
T
host 4cee5a0c53 Fix deploy/rollback to clean code dir before extract
Overlay-only extract left files added by the newer version behind
after a rollback (2026-10-26: after rolling back ops-batch,
deploy/ new scripts were still present). Before every extract,
delete app-dir contents except work/ (task worktrees), then
extract; backup tarballs also exclude work/, so worktrees are
preserved on both deploy and rollback.
2026-10-26 04:41:01 +08:00

81 lines
2.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# 回滚:VM 侧运行,把主机恢复到最近一份代码备份包并重启验证。
#
# 用法:deploy/rollback.sh <host> [user]
# host:主机 IP 或域名(必填);user:SSH 用户(默认 root)。
#
# 密码:与 deploy.sh 同款规则——绝不接受密码参数、不读 env 文件、
# 不打印任何密钥;SSH 密码由交互提示或调用方通道提供;需要代理时
# 用环境变量 SSH_PROXY_CMD 传入 ProxyCommand,未设则直连。
#
# 回滚边界:只回代码,不回数据库(理由见 deploy.sh 头注释与
# deploy/README.md:数据库迁移是只加列的幂等操作,老代码仍能读新列)。
# 备份包来自 deploy.sh 每次部署前在主机上打的
# /opt/codex-app-server-backups/codex-app-server-<时间戳>.tar.gz,
# 本脚本恢复其中最新的一份;主机上没有备份包时直接报错退出,不编造。
set -eu
HOST=${1:-}
USER_ARG=${2:-root}
if [ -z "$HOST" ]; then
echo "用法:deploy/rollback.sh <host> [user]" >&2
exit 2
fi
ssh_cmd() {
if [ -n "${SSH_PROXY_CMD:-}" ]; then
ssh -o "ProxyCommand $SSH_PROXY_CMD" -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null "$@"
else
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$@"
fi
}
ssh_cmd "$USER_ARG@$HOST" 'sh -s' <<'HOST_SCRIPT'
set -eu
APP_DIR=/opt/codex-app-server
BACKUP_DIR=/opt/codex-app-server-backups
check_health() {
OUT=$(curl -s --max-time 5 http://127.0.0.1:8765/health || true)
[ -n "$OUT" ] && printf '%s' "$OUT" | python3 -c '
import json, sys
try:
d = json.load(sys.stdin)
except Exception:
sys.exit(1)
sys.exit(0 if (d.get("ok") is True and d.get("backend") == "postgres"
and d.get("db_ok") is True) else 1)
'
}
wait_health() {
i=0
while [ "$i" -lt 12 ]; do
if check_health; then return 0; fi
sleep 5
i=$((i + 1))
done
return 1
}
BACKUP_FILE=$(ls -t "$BACKUP_DIR"/codex-app-server-*.tar.gz 2>/dev/null \
| head -n 1 || true)
if [ -z "$BACKUP_FILE" ]; then
echo "主机上没有代码备份包,无法回滚:$BACKUP_DIR" >&2
exit 1
fi
echo "将恢复备份包:$BACKUP_FILE"
systemctl stop codex-cloud-worker codex-cloud-server || true
find "$APP_DIR" -mindepth 1 -maxdepth 1 ! -name work -exec rm -rf {} +
tar -xzf "$BACKUP_FILE" -C /opt
chown -R codexsvc:codexsvc "$APP_DIR"
systemctl start codex-cloud-server codex-cloud-worker
if wait_health; then
echo "回滚成功,health 通过,当前代码为备份包:$BACKUP_FILE"
exit 0
fi
echo "回滚后 health 仍失败,需人工介入" >&2
exit 1
HOST_SCRIPT