Add single-exchange instance-only deploy menu options.

Manage menu 4/5/6 install OKX/Binance/Gate Flask only without hub or agents; reuse setup_env --only and narrowed PM2 verify.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-17 15:40:25 +08:00
parent 2269bc51ff
commit 0f12e0a8ea
6 changed files with 300 additions and 44 deletions
+123 -24
View File
@@ -330,9 +330,57 @@ pm2_count_online() {
is_deployed() {
local root="$1"
[[ -x "${root}/crypto_monitor_binance/.venv/bin/python" ]] \
|| [[ -x "${root}/crypto_monitor_gate/.venv/bin/python" ]] \
|| [[ -x "${root}/crypto_monitor_okx/.venv/bin/python" ]] \
|| [[ -x "${root}/manual_trading_hub/.venv/bin/python" ]]
}
# 单所实例: key -> 目录 / PM2 名 / 端口 / 展示名
exchange_dir() {
case "$1" in
okx) echo "crypto_monitor_okx" ;;
binance) echo "crypto_monitor_binance" ;;
gate) echo "crypto_monitor_gate" ;;
*) return 1 ;;
esac
}
exchange_pm2_name() {
case "$1" in
okx) echo "crypto_okx" ;;
binance) echo "crypto_binance" ;;
gate) echo "crypto_gate" ;;
*) return 1 ;;
esac
}
exchange_http_port() {
case "$1" in
okx) echo "5004" ;;
binance) echo "5001" ;;
gate) echo "5000" ;;
*) return 1 ;;
esac
}
exchange_label() {
case "$1" in
okx) echo "OKX" ;;
binance) echo "Binance" ;;
gate) echo "Gate" ;;
*) echo "$1" ;;
esac
}
normalize_exchange_key() {
local k
k="$(echo "${1:-}" | tr '[:upper:]' '[:lower:]' | xargs)"
case "${k}" in
okx|binance|gate) echo "${k}" ;;
*) return 1 ;;
esac
}
check_http() {
local url="$1"
local code
@@ -342,37 +390,62 @@ check_http() {
verify_deployment() {
local ip="${1:-$(detect_server_ip)}"
local mode="${2:-all}"
local ok=1
local online total
local ex_key=""
step "部署验收"
total="${#PM2_APPS[@]}"
online="$(pm2_count_online)"
if [[ "${online}" -eq "${total}" ]]; then
echo " [✓] PM2 进程 ${online}/${total} online"
else
echo " [✗] PM2 进程 ${online}/${total} online"
ok=0
pm2 list 2>/dev/null || true
fi
local checks=(
"中控:http://127.0.0.1:5100/"
"Binance:http://127.0.0.1:5001/"
"Gate:http://127.0.0.1:5000/"
"OKX:http://127.0.0.1:5004/"
)
local item label url
for item in "${checks[@]}"; do
label="${item%%:*}"
url="${item#*:}"
if check_http "${url}"; then
echo " [✓] ${label} 可访问"
if [[ "${mode}" == "all" || -z "${mode}" ]]; then
total="${#PM2_APPS[@]}"
online="$(pm2_count_online)"
if [[ "${online}" -eq "${total}" ]]; then
echo " [✓] PM2 进程 ${online}/${total} online"
else
echo " [✗] ${label} 不可访问 (${url})"
echo " [✗] PM2 进程 ${online}/${total} online"
ok=0
pm2 list 2>/dev/null || true
fi
local checks=(
"中控:http://127.0.0.1:5100/"
"Binance:http://127.0.0.1:5001/"
"Gate:http://127.0.0.1:5000/"
"OKX:http://127.0.0.1:5004/"
)
local item label url
for item in "${checks[@]}"; do
label="${item%%:*}"
url="${item#*:}"
if check_http "${url}"; then
echo " [✓] ${label} 可访问"
else
echo " [✗] ${label} 不可访问 (${url})"
ok=0
fi
done
else
if ! ex_key="$(normalize_exchange_key "${mode}")"; then
echo " [✗] 未知验收模式: ${mode}"
return 1
fi
local pm2_name port label
pm2_name="$(exchange_pm2_name "${ex_key}")"
port="$(exchange_http_port "${ex_key}")"
label="$(exchange_label "${ex_key}")"
if pm2_app_exists "${pm2_name}"; then
echo " [✓] PM2 ${pm2_name} 已注册"
else
echo " [✗] PM2 缺少进程 ${pm2_name}"
ok=0
pm2 list 2>/dev/null || true
fi
if check_http "http://127.0.0.1:${port}/"; then
echo " [✓] ${label} 可访问 (http://127.0.0.1:${port}/)"
else
echo " [✗] ${label} 不可访问 (http://127.0.0.1:${port}/)"
ok=0
fi
done
fi
if [[ "${ok}" -eq 1 ]]; then
echo ""
@@ -410,3 +483,29 @@ print_post_install_guide() {
═══════════════════════════════════════════
EOF
}
print_post_install_guide_instance() {
local ex_key="$1"
local ip="${2:-$(detect_server_ip)}"
local label port
label="$(exchange_label "${ex_key}")"
port="$(exchange_http_port "${ex_key}")"
cat <<EOF
═══════════════════════════════════════════
✅ 单所实例部署完成(不含中控)
${label}: http://${ip}:${port}
登录账号: admin
登录密码: admin123
(请尽快在 env 配置中修改)
下一步(浏览器):
1. ${label} → env 配置 → 填 API、风控、企业微信
2. 开启实盘下单 → 保存并重启该实例进程
说明: 本模式不起中控 / agent;整仓仍在 ${INSTALL_ROOT},仅启动本所 Flask.
═══════════════════════════════════════════
EOF
}
+81 -11
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# deploy/lib/install.sh — 一键部署
# deploy/lib/install.sh — 一键部署(全套) / 单所仅实例
set -e
set -u
if [ -n "${BASH_VERSION:-}" ]; then
@@ -10,6 +10,26 @@ LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=common.sh
source "${LIB_DIR}/common.sh"
EXCHANGE=""
while [[ $# -gt 0 ]]; do
case "$1" in
--exchange)
EXCHANGE="${2:-}"
shift 2
;;
-h|--help)
echo "用法: bash deploy/lib/install.sh [--exchange okx|binance|gate]"
echo " 无 --exchange: 全套(三所+中控)"
echo " 有 --exchange: 仅该所 Flask 实例(不含中控/agent)"
exit 0
;;
*)
echo "未知参数: $1" >&2
exit 1
;;
esac
done
install_fresh() {
step "克隆仓库"
if [[ -d "${INSTALL_ROOT}" ]]; then
@@ -45,6 +65,28 @@ run_install_pipeline() {
print_post_install_guide "$(detect_server_ip)"
}
run_instance_pipeline() {
local ex_key="$1"
local dir_name
dir_name="$(exchange_dir "${ex_key}")"
step "单所环境部署 setup_env.sh --only ${ex_key}(不含中控)"
bash "${REPO_ROOT}/deploy/setup_env.sh" --only "${ex_key}" --install-system-deps
step "启动 PM2 仅 ${dir_name}"
bash "${REPO_ROOT}/deploy/pm2_start_all.sh" --only "${ex_key}"
pm2_save_startup
local cron_script="${REPO_ROOT}/${dir_name}/scripts/install_backup_cron.sh"
if [[ -x "${cron_script}" ]]; then
step "安装 ${ex_key} 备份 cron"
bash "${cron_script}" || true
fi
verify_deployment "$(detect_server_ip)" "${ex_key}" || true
print_post_install_guide_instance "${ex_key}" "$(detect_server_ip)"
}
handle_existing_install() {
echo ""
echo "检测到已部署安装: ${INSTALL_ROOT}"
@@ -72,10 +114,47 @@ handle_existing_install() {
esac
}
ensure_repo_ready() {
if repo_ready "${INSTALL_ROOT}"; then
REPO_ROOT="${INSTALL_ROOT}"
elif [[ -n "${REPO_ROOT:-}" ]] && repo_ready "${REPO_ROOT}"; then
:
else
REPO_ROOT=""
fi
if [[ -z "${REPO_ROOT}" ]]; then
install_system_packages
install_node_pm2
install_fresh
REPO_ROOT="${INSTALL_ROOT}"
else
install_system_packages
install_node_pm2
fi
}
main_install_instance() {
local ex_key="$1"
require_root
require_ubuntu
ensure_repo_ready
run_instance_pipeline "${ex_key}"
}
main_install() {
require_root
require_ubuntu
if [[ -n "${EXCHANGE}" ]]; then
local ex_key=""
if ! ex_key="$(normalize_exchange_key "${EXCHANGE}")"; then
die "无效 --exchange: ${EXCHANGE} (期望 okx|binance|gate)"
fi
main_install_instance "${ex_key}"
return 0
fi
if repo_ready "${INSTALL_ROOT}"; then
REPO_ROOT="${INSTALL_ROOT}"
elif repo_ready "${REPO_ROOT}"; then
@@ -89,16 +168,7 @@ main_install() {
return 0
fi
if [[ -z "${REPO_ROOT}" ]]; then
install_system_packages
install_node_pm2
install_fresh
REPO_ROOT="${INSTALL_ROOT}"
else
install_system_packages
install_node_pm2
fi
ensure_repo_ready
run_install_pipeline
}