09265b608d
Quick update was verifying with stale in-memory functions before Flask bound. Co-authored-by: Cursor <cursoragent@cursor.com>
108 lines
2.6 KiB
Bash
108 lines
2.6 KiB
Bash
#!/usr/bin/env bash
|
|
# 服务器上拉代码并重启 PM2.
|
|
# 用法(/opt/crypto_okx 下 root):
|
|
# bash deploy/pull_and_restart.sh
|
|
# bash deploy/pull_and_restart.sh --dry-run
|
|
set -e
|
|
set -u
|
|
if [ -n "${BASH_VERSION:-}" ]; then
|
|
set -o pipefail
|
|
fi
|
|
|
|
REPO="${REPO:-/opt/crypto_okx}"
|
|
PM2_APP_NAME="${PM2_APP_NAME:-crypto_okx}"
|
|
DRY=0
|
|
if [[ "${1:-}" == "--dry-run" ]]; then
|
|
DRY=1
|
|
echo "(dry-run mode)"
|
|
fi
|
|
|
|
pm2_has_app() {
|
|
local name="$1"
|
|
if ! command -v pm2 >/dev/null 2>&1; then
|
|
return 1
|
|
fi
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
pm2 jlist 2>/dev/null | python3 -c '
|
|
import json,sys
|
|
name=sys.argv[1]
|
|
try:
|
|
apps=json.load(sys.stdin)
|
|
except Exception:
|
|
sys.exit(1)
|
|
sys.exit(0 if any(isinstance(a,dict) and a.get("name")==name for a in (apps or [])) else 1)
|
|
' "${name}"
|
|
return $?
|
|
fi
|
|
pm2 describe "${name}" 2>/dev/null | grep -qE 'status[[:space:]]*[|:]'
|
|
}
|
|
|
|
read_port() {
|
|
local env_file="${REPO}/.env"
|
|
local port="5004"
|
|
if [[ -f "${env_file}" ]]; then
|
|
local line
|
|
line="$(grep -E '^[[:space:]]*APP_PORT=' "${env_file}" | tail -n1 || true)"
|
|
if [[ -n "${line}" ]]; then
|
|
port="${line#*=}"
|
|
port="$(echo "${port}" | tr -d '"' | tr -d "'" | xargs)"
|
|
fi
|
|
fi
|
|
echo "${port:-5004}"
|
|
}
|
|
|
|
wait_http_ready() {
|
|
local port="$1"
|
|
local url="http://127.0.0.1:${port}/"
|
|
local i code
|
|
echo ">>> 等待 HTTP 就绪 ${url} (最多 30s)"
|
|
for i in $(seq 1 30); do
|
|
code="$(curl -sS -o /dev/null -w '%{http_code}' --connect-timeout 2 --max-time 3 "${url}" 2>/dev/null || echo "000")"
|
|
if [[ "${code}" == "200" || "${code}" == "302" || "${code}" == "301" || "${code}" == "401" || "${code}" == "403" ]]; then
|
|
echo ">>> HTTP OK (${code}) after ${i}s"
|
|
return 0
|
|
fi
|
|
# 进程挂了就别空等
|
|
if ! pm2_has_app "${PM2_APP_NAME}"; then
|
|
echo ">>> PM2 进程已消失" >&2
|
|
return 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
echo ">>> HTTP 仍未就绪 (最后 code=${code:-000})" >&2
|
|
echo ">>> 请查看: pm2 logs ${PM2_APP_NAME} --lines 50" >&2
|
|
return 1
|
|
}
|
|
|
|
cd "${REPO}"
|
|
echo ">>> git pull"
|
|
git pull
|
|
|
|
if [[ "${DRY}" -eq 1 ]]; then
|
|
echo "(dry-run, skip pm2 restart)"
|
|
exit 0
|
|
fi
|
|
|
|
if ! command -v pm2 >/dev/null 2>&1; then
|
|
echo "warn: 未安装 pm2" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f ecosystem.config.cjs ]]; then
|
|
echo "error: 缺少 ecosystem.config.cjs" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if pm2_has_app "${PM2_APP_NAME}"; then
|
|
echo ">>> pm2 restart ${PM2_APP_NAME} --update-env"
|
|
pm2 restart "${PM2_APP_NAME}" --update-env
|
|
else
|
|
echo ">>> 未注册 ${PM2_APP_NAME},执行 pm2 start ecosystem.config.cjs"
|
|
pm2 start ecosystem.config.cjs
|
|
fi
|
|
|
|
port="$(read_port)"
|
|
wait_http_ready "${port}" || true
|
|
|
|
echo "done"
|