295 lines
10 KiB
Bash
Executable File
295 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
||
# 本地站点管理:启动 / 停止 / 重启 / 状态
|
||
# 用法:bash sites-manage-local.sh [start|stop|restart|status] [站点名...]
|
||
# 不加参数则交互选择
|
||
#
|
||
# 站点名:
|
||
# cc: www-cc cloud-cc token-cc
|
||
# ai: www-ai cloud-ai token-ai issue assets ldap
|
||
# all: 全部站点
|
||
|
||
set -e
|
||
|
||
BASE_DIR="/Users/niuniu/programs/docker"
|
||
ISSUE_DIR="$BASE_DIR/issue-ai"
|
||
ASSETS_DIR="$BASE_DIR/assets-ai"
|
||
LDAP_DIR="$BASE_DIR/ldap-ai"
|
||
OA_DIR="$BASE_DIR/oa-ai"
|
||
OA_PORT=6179
|
||
|
||
# 颜色
|
||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
||
log() { printf "${GREEN}[✓]${NC} %s\n" "$1"; }
|
||
warn() { printf "${YELLOW}[!]${NC} %s\n" "$1"; }
|
||
err() { printf "${RED}[✗]${NC} %s\n" "$1"; }
|
||
|
||
# 端口
|
||
ISSUE_PORT=6176
|
||
ASSETS_PORT=6177
|
||
LDAP_WEB_PORT=6178
|
||
|
||
is_port() { lsof -i :"$1" >/dev/null 2>&1; }
|
||
is_running() { docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^$1$"; }
|
||
|
||
# ============================================================
|
||
# 单个 Docker 站点操作
|
||
# ============================================================
|
||
docker_start() {
|
||
local name=$1 dir=$2
|
||
if is_running $name; then
|
||
warn "$name 已在运行"
|
||
else
|
||
log "启动 $name..."
|
||
cd "$dir" && docker compose up -d 2>/dev/null && log "$name 已启动" || err "$name 启动失败"
|
||
fi
|
||
}
|
||
docker_stop() {
|
||
local name=$1 dir=$2
|
||
if is_running $name; then
|
||
log "停止 $name..."
|
||
cd "$dir" && docker compose down 2>/dev/null && log "$name 已停止" || err "$name 停止失败"
|
||
else
|
||
warn "$name 未在运行"
|
||
fi
|
||
}
|
||
|
||
# ============================================================
|
||
# 单个 Node.js 服务(npm run dev)
|
||
# ============================================================
|
||
node_start() {
|
||
local name=$1 dir=$2 port=$3 logfile=$4
|
||
if is_port $port; then
|
||
warn "$name 已在运行 (port $port)"
|
||
else
|
||
log "启动 $name (port $port)..."
|
||
cd "$dir" && npm run dev > "$logfile" 2>&1 &
|
||
sleep 2
|
||
is_port $port && log "$name 已启动" || err "$name 启动失败,请查看 $logfile"
|
||
fi
|
||
}
|
||
node_stop() {
|
||
local name=$1 port=$2
|
||
if is_port $port; then
|
||
kill $(lsof -ti :$port) 2>/dev/null && log "$name 已停止" || warn "$name 停止失败"
|
||
else
|
||
warn "$name 未在运行"
|
||
fi
|
||
}
|
||
|
||
# ============================================================
|
||
# 批量操作
|
||
# ============================================================
|
||
start_all() {
|
||
for name in "$@"; do
|
||
case $name in
|
||
www-cc) docker_start www-local "$BASE_DIR/www-cc" ;;
|
||
cloud-cc) docker_start cloud-cc "$BASE_DIR/cloud-cc" ;;
|
||
token-cc) docker_start token-cc "$BASE_DIR/token-cc" ;;
|
||
www-ai) docker_start www-local-ai "$BASE_DIR/www-ai" ;;
|
||
cloud-ai) docker_start cloud-ai "$BASE_DIR/cloud-ai" ;;
|
||
token-ai) docker_start token-ai "$BASE_DIR/token-ai" ;;
|
||
issue) node_start issue-ai "$ISSUE_DIR" $ISSUE_PORT "/tmp/issue-ai-dev.log"
|
||
if ! is_port $ASSETS_PORT; then
|
||
node_start assets-ai "$ASSETS_DIR" $ASSETS_PORT "/tmp/assets-ai-dev.log"
|
||
warn "已自动启动 assets-ai(issue 依赖 assets API)"
|
||
fi ;;
|
||
assets) node_start assets-ai "$ASSETS_DIR" $ASSETS_PORT "/tmp/assets-ai-dev.log" ;;
|
||
ldap) docker_start lldap "$LDAP_DIR"
|
||
if is_port $LDAP_WEB_PORT; then
|
||
log "LLDAP Web UI: http://localhost:$LDAP_WEB_PORT"
|
||
fi ;;
|
||
oa) node_start oa-ai "$OA_DIR" $OA_PORT "/tmp/oa-ai-dev.log" ;;
|
||
cc) start_all www-cc cloud-cc token-cc ;;
|
||
ai) start_all ldap www-ai cloud-ai token-ai issue assets oa ;;
|
||
all) start_all cc ai ;;
|
||
*) err "未知站点: $name" ;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
stop_all() {
|
||
for name in "$@"; do
|
||
case $name in
|
||
www-cc) docker_stop www-local "$BASE_DIR/www-cc" ;;
|
||
cloud-cc) docker_stop cloud-cc "$BASE_DIR/cloud-cc" ;;
|
||
token-cc) docker_stop token-cc "$BASE_DIR/token-cc" ;;
|
||
www-ai) docker_stop www-local-ai "$BASE_DIR/www-ai" ;;
|
||
cloud-ai) docker_stop cloud-ai "$BASE_DIR/cloud-ai" ;;
|
||
token-ai) docker_stop token-ai "$BASE_DIR/token-ai" ;;
|
||
issue) node_stop issue-ai $ISSUE_PORT ;;
|
||
assets) node_stop assets-ai $ASSETS_PORT ;;
|
||
ldap) docker_stop lldap "$LDAP_DIR" ;;
|
||
oa) node_stop oa-ai $OA_PORT ;;
|
||
cc) stop_all www-cc cloud-cc token-cc ;;
|
||
ai) stop_all ldap www-ai cloud-ai token-ai issue assets oa ;;
|
||
all) stop_all cc ai ;;
|
||
*) err "未知站点: $name" ;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
restart_all() {
|
||
stop_all "$@"
|
||
echo ""
|
||
log "正在重启..."
|
||
start_all "$@"
|
||
}
|
||
|
||
# ============================================================
|
||
# 状态
|
||
# ============================================================
|
||
show_status() {
|
||
local targets=("$@")
|
||
# 合并 all/cc/ai
|
||
local expanded=()
|
||
for t in "${targets[@]}"; do
|
||
case $t in
|
||
all) eval "expanded=(www-cc cloud-cc token-cc ldap www-ai cloud-ai token-ai issue assets oa)" ;;
|
||
cc) eval "expanded=(\${expanded[@]} www-cc cloud-cc token-cc)" ;;
|
||
ai) eval "expanded=(\${expanded[@]} ldap www-ai cloud-ai token-ai issue assets oa)" ;;
|
||
*) expanded+=($t) ;;
|
||
esac
|
||
done
|
||
|
||
echo ""
|
||
printf "${CYAN}=========================================${NC}\n"
|
||
printf "${CYAN} 当前状态${NC}\n"
|
||
printf "${CYAN}=========================================${NC}\n"
|
||
echo ""
|
||
|
||
local running=0
|
||
for name in "${expanded[@]}"; do
|
||
case $name in
|
||
www-cc|cloud-cc|token-cc|cloud-ai|token-ai)
|
||
if is_running $name; then
|
||
printf " ${GREEN}●${NC} %-12s 运行中\n" "$name"
|
||
running=$((running + 1))
|
||
else
|
||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
||
fi
|
||
;;
|
||
www-ai)
|
||
if is_running www-local-ai; then
|
||
printf " ${GREEN}●${NC} %-12s 运行中\n" "$name"
|
||
running=$((running + 1))
|
||
else
|
||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
||
fi
|
||
;;
|
||
issue)
|
||
if is_port $ISSUE_PORT; then
|
||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $ISSUE_PORT
|
||
running=$((running + 1))
|
||
else
|
||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
||
fi
|
||
;;
|
||
ldap)
|
||
if is_running lldap; then
|
||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $LDAP_WEB_PORT
|
||
running=$((running + 1))
|
||
else
|
||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
||
fi
|
||
;;
|
||
assets)
|
||
if is_port $ASSETS_PORT; then
|
||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $ASSETS_PORT
|
||
running=$((running + 1))
|
||
else
|
||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
||
fi
|
||
;;
|
||
oa)
|
||
if is_port $OA_PORT; then
|
||
printf " ${GREEN}●${NC} %-12s 运行中 (port %d)\n" "$name" $OA_PORT
|
||
running=$((running + 1))
|
||
else
|
||
printf " ${RED}●${NC} %-12s 未运行\n" "$name"
|
||
fi
|
||
;;
|
||
esac
|
||
done
|
||
echo ""
|
||
|
||
printf "${CYAN}=========================================${NC}\n"
|
||
printf "${CYAN} 访问地址${NC}\n"
|
||
printf "${CYAN}=========================================${NC}\n"
|
||
echo ""
|
||
echo " cc 站点:"
|
||
echo " www-cc http://localhost:5173"
|
||
echo " cloud-cc http://localhost:5174"
|
||
echo " token-cc http://localhost:5175"
|
||
echo ""
|
||
echo " ai 站点:"
|
||
echo " www-ai http://localhost:6173"
|
||
echo " cloud-ai http://localhost:6174"
|
||
echo " token-ai http://localhost:6175"
|
||
echo " ldap http://localhost:$LDAP_WEB_PORT (LLDAP Web UI)"
|
||
echo " oa http://localhost:$OA_PORT"
|
||
echo " issue http://localhost:$ISSUE_PORT"
|
||
echo " assets http://localhost:$ASSETS_PORT"
|
||
echo ""
|
||
}
|
||
|
||
# ============================================================
|
||
# 帮助
|
||
# ============================================================
|
||
show_help() {
|
||
echo ""
|
||
printf "${CYAN}用法:${NC} bash sites-manage-local.sh <命令> [站点名...]\n"
|
||
echo ""
|
||
echo " 命令:"
|
||
echo " start 启动站点"
|
||
echo " stop 停止站点"
|
||
echo " restart 重启站点"
|
||
echo " status 查看状态"
|
||
echo ""
|
||
echo " 站点名(可指定多个,空格分隔):"
|
||
echo " www-cc cloud-cc token-cc"
|
||
echo " ldap www-ai cloud-ai token-ai issue assets oa"
|
||
echo " cc — tlyq.cc 全部 (www-cc cloud-cc token-cc)"
|
||
echo " ai — tlyq.ai 全部 (ldap www-ai cloud-ai token-ai issue assets oa)"
|
||
echo " all — 全部站点"
|
||
echo ""
|
||
echo "示例:"
|
||
echo " bash sites-manage-local.sh start all # 启动全部"
|
||
echo " bash sites-manage-local.sh start ai # 启动 ai 全部"
|
||
echo " bash sites-manage-local.sh start issue assets # 只启 issue + assets"
|
||
echo " bash sites-manage-local.sh stop www-ai # 只停 www-ai"
|
||
echo " bash sites-manage-local.sh status # 查看所有状态"
|
||
echo ""
|
||
}
|
||
|
||
# ============================================================
|
||
# 入口
|
||
# ============================================================
|
||
ACTION=${1:-}
|
||
shift || true
|
||
|
||
if [ -z "$ACTION" ]; then
|
||
show_help
|
||
exit 0
|
||
fi
|
||
|
||
# 解析站点列表
|
||
if [ $# -eq 0 ]; then
|
||
case $ACTION in
|
||
start|stop|restart) TARGETS=(all) ;;
|
||
status) TARGETS=(all) ;;
|
||
help|--help|-h) show_help; exit 0 ;;
|
||
*) err "未知命令: $ACTION"; show_help; exit 1 ;;
|
||
esac
|
||
else
|
||
TARGETS=("$@")
|
||
fi
|
||
|
||
case $ACTION in
|
||
start) start_all "${TARGETS[@]}" ;;
|
||
stop) stop_all "${TARGETS[@]}" ;;
|
||
restart) restart_all "${TARGETS[@]}" ;;
|
||
status) show_status "${TARGETS[@]}" ;;
|
||
help|--help|-h) show_help ;;
|
||
*) err "未知命令: $ACTION"; show_help; exit 1 ;;
|
||
esac
|