Files
BoosAPI/update-and-restart.sh
Bainily 1449f08e6c fix: stabilize Codex continuation and proxy retry recovery / 修复 Codex 续传与代理重试稳定性 (#257)
* wip: preserve local changes before upstream merge

* Improve proxy routing stability and add stable-first strategy

* Sync explicit-group routing strategy to eligible source routes

* Fix proxy retry and runtime health review issues

* fix: make proxy channel retry attempts configurable

* fix: harden proxy retry recovery and bookkeeping

* fix: address pr 257 review comments

---------

Co-authored-by: Cita <juricek.chen@gmail.com>
2026-03-23 19:17:22 +08:00

160 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="$ROOT_DIR/docker/docker-compose.yml"
COMPOSE_OVERRIDE_FILE="$ROOT_DIR/docker/docker-compose.override.yml"
ENV_FILE="$ROOT_DIR/docker/.env"
DATA_DIR="$ROOT_DIR/docker/data"
DO_PULL=0
SKIP_BACKUP=0
usage() {
cat <<'EOF'
Usage: ./update-and-restart.sh [--pull] [--skip-backup]
默认行为:
1. 保留现有 docker/data 数据
2. 先备份数据目录
3. 基于当前本地代码重新构建并重启容器
可选参数:
--pull 先拉取最新 Git 代码后再构建。若工作区有未提交修改会直接退出,避免覆盖本地改动
--skip-backup 跳过启动前数据备份
-h, --help 显示帮助
EOF
}
require_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Missing required command: $1" >&2
exit 1
fi
}
require_file() {
if [ ! -f "$1" ]; then
echo "Missing required file: $1" >&2
exit 1
fi
}
while [ $# -gt 0 ]; do
case "$1" in
--pull)
DO_PULL=1
;;
--skip-backup)
SKIP_BACKUP=1
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 1
;;
esac
shift
done
require_cmd docker
require_cmd tar
require_cmd git
require_file "$COMPOSE_FILE"
require_file "$ENV_FILE"
COMPOSE_ARGS=(
-f "$COMPOSE_FILE"
--env-file "$ENV_FILE"
)
if [ -f "$COMPOSE_OVERRIDE_FILE" ]; then
COMPOSE_ARGS=(
-f "$COMPOSE_FILE"
-f "$COMPOSE_OVERRIDE_FILE"
--env-file "$ENV_FILE"
)
fi
if [ "$DO_PULL" -eq 1 ]; then
echo "[0/5] Checking git worktree..."
if [ -n "$(git -C "$ROOT_DIR" status --porcelain)" ]; then
echo "Git worktree has uncommitted changes. Commit/stash them first, or rerun without --pull to rebuild the current local code." >&2
exit 1
fi
echo "[1/5] Pulling latest git changes..."
git -C "$ROOT_DIR" pull --rebase
else
echo "[1/4] Using current local source code..."
fi
BACKUP_FILE=""
RESTORE_ON_ERROR=0
restore_if_failed() {
if [ "$RESTORE_ON_ERROR" -eq 1 ]; then
echo "Update failed after containers were stopped; attempting to restore service..." >&2
docker compose "${COMPOSE_ARGS[@]}" up -d --force-recreate || true
fi
}
trap restore_if_failed ERR
if [ "$DO_PULL" -eq 1 ]; then
echo "[2/5] Stopping current containers..."
else
echo "[2/4] Stopping current containers..."
fi
docker compose "${COMPOSE_ARGS[@]}" down --remove-orphans
RESTORE_ON_ERROR=1
if [ "$SKIP_BACKUP" -eq 0 ]; then
mkdir -p "$DATA_DIR"
BACKUP_FILE="$ROOT_DIR/docker/data-backup-$(date +%Y%m%d-%H%M%S).tar.gz"
if [ "$DO_PULL" -eq 1 ]; then
echo "[3/5] Backing up data directory..."
else
echo "[3/4] Backing up data directory..."
fi
tar -czf "$BACKUP_FILE" -C "$DATA_DIR" .
else
if [ "$DO_PULL" -eq 1 ]; then
echo "[3/5] Skipping data backup by request..."
else
echo "[3/4] Skipping data backup by request..."
fi
fi
if [ "$DO_PULL" -eq 1 ]; then
echo "[4/5] Rebuilding and starting containers..."
else
echo "[4/4] Rebuilding and starting containers..."
fi
docker compose "${COMPOSE_ARGS[@]}" up -d --build --force-recreate
RESTORE_ON_ERROR=0
trap - ERR
echo
echo "Container status:"
docker compose "${COMPOSE_ARGS[@]}" ps
echo
echo "Recent logs:"
docker compose "${COMPOSE_ARGS[@]}" logs --tail 20
if [ -n "$BACKUP_FILE" ]; then
echo
echo "Data backup saved to: $BACKUP_FILE"
fi
if PORT_MAPPING="$(docker compose "${COMPOSE_ARGS[@]}" port metapi 4000 2>/dev/null)"; then
echo
echo "Service is available at: $PORT_MAPPING"
fi