优化 run.sh 三种部署方式的升级清理逻辑
- 共用 clean/build 函数,升级前清理 frontend/dist、backend/static 与旧二进制 - binary upgrade/start/stop/status:停服、备份、重编译、后台启动并持久化启动参数 - docker up/upgrade:--force-recreate --remove-orphans,支持 up fresh 无缓存重建 - kubernetes upgrade:--no-cache 构建 + 时间戳镜像 tag,set image 触发滚动更新
This commit is contained in:
1 parent
921b44d6a4
commit
ac69ae75d4
1 file changed
+356
-110
@@ -14,7 +14,8 @@
|
||||
#
|
||||
# 方式 3 — 独立二进制:
|
||||
# ./run.sh build 编译独立二进制 (embed 前端)
|
||||
# ./run.sh binary 编译并启动
|
||||
# ./run.sh binary upgrade 停服 → 清旧产物 → 重编译 → 后台启动
|
||||
# ./run.sh binary start|stop|status
|
||||
#
|
||||
# 本地开发:
|
||||
# ./run.sh dev 前后端热重载
|
||||
@@ -60,6 +61,8 @@ cd "$SCRIPT_DIR"
|
||||
# PID 文件
|
||||
BACKEND_PID_FILE="$SCRIPT_DIR/$BACKEND_DIR/.backend.pid"
|
||||
FRONTEND_PID_FILE="$SCRIPT_DIR/$FRONTEND_DIR/.frontend.pid"
|
||||
BINARY_PID_FILE="$SCRIPT_DIR/$BACKEND_DIR/.aiops.pid"
|
||||
BINARY_ARGS_FILE="$SCRIPT_DIR/$BACKEND_DIR/.aiops.args"
|
||||
|
||||
# 检测操作系统
|
||||
detect_os() {
|
||||
@@ -290,6 +293,196 @@ cmd_logs() {
|
||||
wait
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# 构建清理(三种部署方式共用,避免旧代码/旧静态资源残留)// Logan.Li
|
||||
# ============================================================
|
||||
clean_frontend_artifacts() {
|
||||
info "清理前端旧构建产物..."
|
||||
rm -rf "$SCRIPT_DIR/$FRONTEND_DIR/dist"
|
||||
rm -rf "$SCRIPT_DIR/$FRONTEND_DIR/node_modules/.vite"
|
||||
}
|
||||
|
||||
clean_embed_static() {
|
||||
info "清理 embed static 旧文件..."
|
||||
mkdir -p "$SCRIPT_DIR/$BACKEND_DIR/static"
|
||||
find "$SCRIPT_DIR/$BACKEND_DIR/static" -mindepth 1 -delete 2>/dev/null || rm -rf "$SCRIPT_DIR/$BACKEND_DIR/static"/*
|
||||
}
|
||||
|
||||
clean_go_artifacts() {
|
||||
info "清理 Go 旧编译产物..."
|
||||
rm -f "$SCRIPT_DIR/$BACKEND_DIR/$STANDALONE_BIN"
|
||||
rm -f "$SCRIPT_DIR/$BACKEND_DIR/$BACKEND_BIN"
|
||||
}
|
||||
|
||||
# 构建前端并同步到 backend/static(二进制 / embed 镜像共用)// Logan.Li
|
||||
build_frontend_embed() {
|
||||
clean_frontend_artifacts
|
||||
cd "$SCRIPT_DIR/$FRONTEND_DIR"
|
||||
if [ ! -d "node_modules" ]; then
|
||||
npm install --registry=https://registry.npmmirror.com
|
||||
fi
|
||||
npm run build 2>&1 | tail -8
|
||||
cd "$SCRIPT_DIR"
|
||||
clean_embed_static
|
||||
cp -r "$FRONTEND_DIR/dist/"* "$BACKEND_DIR/static/"
|
||||
local fe_files
|
||||
fe_files=$(find "$BACKEND_DIR/static" -type f | wc -l | tr -d ' ')
|
||||
success "前端已嵌入 static/ ($fe_files 个文件)"
|
||||
}
|
||||
|
||||
# 停止独立二进制进程(PID 文件 + 端口双保险)// Logan.Li
|
||||
stop_binary_process() {
|
||||
local port=${1:-8080}
|
||||
if [ -f "$BINARY_PID_FILE" ]; then
|
||||
local pid
|
||||
pid=$(cat "$BINARY_PID_FILE" 2>/dev/null || echo "")
|
||||
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||
kill "$pid" 2>/dev/null || true
|
||||
sleep 1
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
success "已停止二进制进程 (PID: $pid)"
|
||||
fi
|
||||
rm -f "$BINARY_PID_FILE"
|
||||
fi
|
||||
# 兜底:按端口和进程名清理残留
|
||||
if [ "$OS" = "macos" ]; then
|
||||
local pids
|
||||
pids=$(lsof -ti:"$port" 2>/dev/null || echo "")
|
||||
[ -n "$pids" ] && echo "$pids" | xargs kill -9 2>/dev/null || true
|
||||
else
|
||||
fuser -k "${port}/tcp" 2>/dev/null || true
|
||||
pkill -f "${SCRIPT_DIR}/${BACKEND_DIR}/${STANDALONE_BIN}" 2>/dev/null || true
|
||||
pkill -f "./${STANDALONE_BIN} --port" 2>/dev/null || true
|
||||
fi
|
||||
sleep 0.5
|
||||
}
|
||||
|
||||
wait_binary_ready() {
|
||||
local port=${1:-8080}
|
||||
local retries=0
|
||||
while ! curl -sf "http://localhost:${port}/version" > /dev/null 2>&1; do
|
||||
retries=$((retries + 1))
|
||||
if [ $retries -ge 30 ]; then
|
||||
error "二进制启动超时,查看日志: $BACKEND_DIR/logs/aiops.log"
|
||||
tail -20 "$SCRIPT_DIR/$BACKEND_DIR/logs/aiops.log" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# 确保二进制默认 config.yaml 存在 // Logan.Li
|
||||
ensure_binary_config() {
|
||||
local cfg="$SCRIPT_DIR/$BACKEND_DIR/config.yaml"
|
||||
if [ -f "$cfg" ]; then
|
||||
return 0
|
||||
fi
|
||||
info "生成默认 config.yaml (SQLite + 无Redis)..."
|
||||
cat > "$cfg" << 'YAML'
|
||||
mode: "release"
|
||||
port: "8080"
|
||||
log_level: "info"
|
||||
|
||||
database:
|
||||
driver: "sqlite"
|
||||
host: "localhost"
|
||||
port: 3306
|
||||
user: ""
|
||||
password: ""
|
||||
dbname: "data/aiops.db"
|
||||
charset: "utf8mb4"
|
||||
max_conn: 100
|
||||
max_idle: 10
|
||||
|
||||
redis:
|
||||
host: "localhost"
|
||||
port: 6379
|
||||
password: ""
|
||||
db: 0
|
||||
|
||||
jwt:
|
||||
secret: "CHANGE_ME_JWT_SECRET" # ⚠️ 生产环境必须替换
|
||||
expire_hour: 24
|
||||
|
||||
websocket:
|
||||
read_buffer_size: 1024
|
||||
write_buffer_size: 1024
|
||||
YAML
|
||||
}
|
||||
|
||||
# 编译独立二进制(含 embed 前端)// Logan.Li
|
||||
build_standalone_binary() {
|
||||
build_frontend_embed
|
||||
ensure_binary_config
|
||||
clean_go_artifacts
|
||||
cd "$SCRIPT_DIR/$BACKEND_DIR"
|
||||
info "编译中..."
|
||||
CGO_ENABLED=1 GOPROXY=https://goproxy.cn,direct GONOSUMCHECK='*' GOTOOLCHAIN=go1.24.0 \
|
||||
go build -ldflags="-w -s" -o "$STANDALONE_BIN" .
|
||||
if [ ! -f "$STANDALONE_BIN" ]; then
|
||||
error "编译失败"
|
||||
return 1
|
||||
fi
|
||||
local bin_size
|
||||
bin_size=$(du -h "$STANDALONE_BIN" | cut -f1)
|
||||
success "编译完成: $BACKEND_DIR/$STANDALONE_BIN ($bin_size)"
|
||||
cd "$SCRIPT_DIR"
|
||||
return 0
|
||||
}
|
||||
|
||||
# 解析/持久化二进制启动参数 // Logan.Li
|
||||
save_binary_args() {
|
||||
printf '%s\n' "$@" > "$BINARY_ARGS_FILE"
|
||||
}
|
||||
|
||||
load_binary_args() {
|
||||
local -n _out=$1
|
||||
_out=()
|
||||
if [ -f "$BINARY_ARGS_FILE" ]; then
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
[ -n "$line" ] && _out+=("$line")
|
||||
done < "$BINARY_ARGS_FILE"
|
||||
fi
|
||||
if [ ${#_out[@]} -eq 0 ]; then
|
||||
_out=(--port 8080 --db-driver sqlite)
|
||||
fi
|
||||
}
|
||||
|
||||
binary_listen_port() {
|
||||
local args=("$@")
|
||||
local i=0
|
||||
while [ $i -lt ${#args[@]} ]; do
|
||||
if [ "${args[$i]}" = "--port" ] && [ $((i + 1)) -lt ${#args[@]} ]; then
|
||||
echo "${args[$((i + 1))]}"
|
||||
return 0
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done
|
||||
echo "8080"
|
||||
}
|
||||
|
||||
# 后台启动独立二进制 // Logan.Li
|
||||
start_binary_daemon() {
|
||||
local args=("$@")
|
||||
local port
|
||||
port=$(binary_listen_port "${args[@]}")
|
||||
cd "$SCRIPT_DIR/$BACKEND_DIR"
|
||||
mkdir -p data logs uploads
|
||||
rotate_log "logs/aiops.log"
|
||||
stop_binary_process "$port"
|
||||
nohup ./"$STANDALONE_BIN" "${args[@]}" >> logs/aiops.log 2>&1 &
|
||||
echo $! > "$BINARY_PID_FILE"
|
||||
save_binary_args "${args[@]}"
|
||||
if wait_binary_ready "$port"; then
|
||||
success "二进制已启动 (PID: $(cat "$BINARY_PID_FILE"), 端口: $port)"
|
||||
info "日志: $BACKEND_DIR/logs/aiops.log"
|
||||
info "健康检查: http://localhost:${port}/version"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
# Docker Compose 部署
|
||||
# ============================================================
|
||||
@@ -331,9 +524,21 @@ cmd_docker() {
|
||||
info "BuildKit: 已启用 (增量编译 + 缓存复用)"
|
||||
|
||||
case "$action" in
|
||||
up)
|
||||
banner "========== Docker Compose 启动 =========="
|
||||
$DOCKER_COMPOSE up -d --build
|
||||
up|upgrade|update)
|
||||
local fresh_build=0
|
||||
if [ "${2:-}" = "fresh" ] || [ "$action" = "fresh" ]; then
|
||||
fresh_build=1
|
||||
fi
|
||||
banner "========== Docker Compose 启动/升级 =========="
|
||||
clean_frontend_artifacts
|
||||
if [ "$fresh_build" -eq 1 ]; then
|
||||
info "全量重建镜像 (--no-cache)..."
|
||||
$DOCKER_COMPOSE build --no-cache
|
||||
$DOCKER_COMPOSE up -d --force-recreate --remove-orphans
|
||||
else
|
||||
info "增量构建 + 强制重建容器..."
|
||||
$DOCKER_COMPOSE up -d --build --force-recreate --remove-orphans
|
||||
fi
|
||||
echo ""
|
||||
# 清理历史 build cache 和悬空镜像,防止占满磁盘
|
||||
info "清理历史构建缓存..."
|
||||
@@ -389,15 +594,20 @@ cmd_docker() {
|
||||
echo " $(df -h / | awk 'NR==2{print $3, "used /", $2, "total ("$5")"}')"
|
||||
success "清理完成"
|
||||
;;
|
||||
fresh)
|
||||
cmd_docker up fresh
|
||||
;;
|
||||
help|--help|-h)
|
||||
echo "Docker Compose 部署命令:"
|
||||
echo " ./run.sh docker up 构建并启动所有容器"
|
||||
echo " ./run.sh docker down 停止并移除容器"
|
||||
echo " ./run.sh docker build 仅构建镜像"
|
||||
echo " ./run.sh docker restart 重启容器"
|
||||
echo " ./run.sh docker logs 查看实时日志"
|
||||
echo " ./run.sh docker ps 查看容器状态"
|
||||
echo " ./run.sh docker clean 清理构建缓存/无用镜像"
|
||||
echo " ./run.sh docker up 增量构建 + 强制重建容器"
|
||||
echo " ./run.sh docker up fresh 无缓存全量重建镜像并启动"
|
||||
echo " ./run.sh docker upgrade 同 up(升级别名)"
|
||||
echo " ./run.sh docker down 停止并移除容器"
|
||||
echo " ./run.sh docker build 仅构建镜像"
|
||||
echo " ./run.sh docker restart 重启容器"
|
||||
echo " ./run.sh docker logs 查看实时日志"
|
||||
echo " ./run.sh docker ps 查看容器状态"
|
||||
echo " ./run.sh docker clean 清理构建缓存/无用镜像"
|
||||
;;
|
||||
*)
|
||||
error "未知 docker 子命令: $action"
|
||||
@@ -416,78 +626,12 @@ cmd_build() {
|
||||
case "$target" in
|
||||
binary|aiops)
|
||||
banner "========== 编译独立二进制 =========="
|
||||
|
||||
# 构建前端 → 拷贝到 embed 目录(go:embed 需要 static/ 下有文件)
|
||||
info "构建前端 → embed..."
|
||||
cd "$SCRIPT_DIR/$FRONTEND_DIR"
|
||||
if [ ! -d "node_modules" ]; then
|
||||
npm install --registry=https://registry.npmmirror.com
|
||||
fi
|
||||
npm run build 2>&1 | tail -5
|
||||
|
||||
# 拷贝前端构建产物到后端 embed 目录
|
||||
cd "$SCRIPT_DIR"
|
||||
rm -rf "$BACKEND_DIR/static"/*
|
||||
cp -r "$FRONTEND_DIR/dist/"* "$BACKEND_DIR/static/"
|
||||
local fe_files=$(find "$BACKEND_DIR/static" -type f | wc -l)
|
||||
success "前端已嵌入 ($fe_files 文件)"
|
||||
|
||||
cd "$SCRIPT_DIR/$BACKEND_DIR"
|
||||
|
||||
# 确保 config.yaml 存在(二进制模式默认 SQLite)
|
||||
if [ ! -f "config.yaml" ]; then
|
||||
info "生成默认 config.yaml (SQLite + 无Redis)..."
|
||||
cat > config.yaml << 'YAML'
|
||||
mode: "release"
|
||||
port: "8080"
|
||||
log_level: "info"
|
||||
|
||||
database:
|
||||
driver: "sqlite"
|
||||
host: "localhost"
|
||||
port: 3306
|
||||
user: ""
|
||||
password: ""
|
||||
dbname: "data/aiops.db"
|
||||
charset: "utf8mb4"
|
||||
max_conn: 100
|
||||
max_idle: 10
|
||||
|
||||
redis:
|
||||
host: "localhost"
|
||||
port: 6379
|
||||
password: ""
|
||||
db: 0
|
||||
|
||||
jwt:
|
||||
secret: "CHANGE_ME_JWT_SECRET" # ⚠️ 生产环境必须替换
|
||||
expire_hour: 24
|
||||
|
||||
websocket:
|
||||
read_buffer_size: 1024
|
||||
write_buffer_size: 1024
|
||||
YAML
|
||||
fi
|
||||
|
||||
# 静态编译(CGO_ENABLED=1 因为 SQLite 需要 CGO)
|
||||
info "编译中..."
|
||||
CGO_ENABLED=1 GOPROXY=https://goproxy.cn,direct GONOSUMCHECK='*' GOTOOLCHAIN=go1.24.0 go build -ldflags="-w -s" -o "$STANDALONE_BIN" .
|
||||
|
||||
if [ -f "$STANDALONE_BIN" ]; then
|
||||
local bin_size=$(du -h "$STANDALONE_BIN" | cut -f1)
|
||||
success "编译完成: $BACKEND_DIR/$STANDALONE_BIN ($bin_size)"
|
||||
echo ""
|
||||
info "使用方法:"
|
||||
echo " ./$BACKEND_DIR/$STANDALONE_BIN # 默认启动 (SQLite, 端口 8080)"
|
||||
echo " ./$BACKEND_DIR/$STANDALONE_BIN --port 9090 # 自定义端口"
|
||||
echo " ./$BACKEND_DIR/$STANDALONE_BIN --db-driver mysql \\"
|
||||
echo " --db-host localhost --db-user root \\"
|
||||
echo " --db-password pass --db-name aiops # MySQL 模式"
|
||||
echo " ./$BACKEND_DIR/$STANDALONE_BIN --config config.yaml # 使用配置文件"
|
||||
else
|
||||
error "编译失败"
|
||||
exit 1
|
||||
fi
|
||||
build_standalone_binary || exit 1
|
||||
echo ""
|
||||
info "使用方法:"
|
||||
echo " ./run.sh binary upgrade # 停服重编译并后台启动"
|
||||
echo " ./$BACKEND_DIR/$STANDALONE_BIN --port 8080 # 前台启动"
|
||||
echo " ./$BACKEND_DIR/$STANDALONE_BIN --config config.yaml # 使用配置文件"
|
||||
;;
|
||||
agent)
|
||||
banner "========== 编译 Agent =========="
|
||||
@@ -531,19 +675,96 @@ YAML
|
||||
# 独立二进制模式
|
||||
# ============================================================
|
||||
cmd_binary() {
|
||||
cd "$SCRIPT_DIR/$BACKEND_DIR"
|
||||
|
||||
# 先编译(如果不存在)
|
||||
if [ ! -f "$STANDALONE_BIN" ]; then
|
||||
info "二进制不存在,先编译..."
|
||||
cmd_build binary
|
||||
local action="run"
|
||||
if [ $# -gt 0 ] && [[ "$1" =~ ^(upgrade|start|stop|status|help|--help|-h)$ ]]; then
|
||||
action=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
banner "========== 启动独立二进制 =========="
|
||||
mkdir -p data logs uploads
|
||||
|
||||
# 传递额外参数
|
||||
./"$STANDALONE_BIN" "$@"
|
||||
case "$action" in
|
||||
upgrade|update)
|
||||
banner "========== 二进制升级部署 =========="
|
||||
local args=()
|
||||
if [ $# -gt 0 ]; then
|
||||
args=("$@")
|
||||
else
|
||||
load_binary_args args
|
||||
fi
|
||||
local port
|
||||
port=$(binary_listen_port "${args[@]}")
|
||||
info "启动参数: ${args[*]}"
|
||||
stop_binary_process "$port"
|
||||
if [ -f "$SCRIPT_DIR/$BACKEND_DIR/$STANDALONE_BIN" ]; then
|
||||
local backup="$SCRIPT_DIR/$BACKEND_DIR/${STANDALONE_BIN}.bak.$(date +%Y%m%d%H%M%S)"
|
||||
cp "$SCRIPT_DIR/$BACKEND_DIR/$STANDALONE_BIN" "$backup"
|
||||
info "已备份旧二进制: $backup"
|
||||
fi
|
||||
build_standalone_binary || exit 1
|
||||
start_binary_daemon "${args[@]}" || exit 1
|
||||
;;
|
||||
start)
|
||||
local args=()
|
||||
if [ $# -gt 0 ]; then
|
||||
args=("$@")
|
||||
else
|
||||
load_binary_args args
|
||||
fi
|
||||
if [ ! -f "$SCRIPT_DIR/$BACKEND_DIR/$STANDALONE_BIN" ]; then
|
||||
info "二进制不存在,先编译..."
|
||||
build_standalone_binary || exit 1
|
||||
fi
|
||||
start_binary_daemon "${args[@]}" || exit 1
|
||||
;;
|
||||
stop)
|
||||
local port=${1:-8080}
|
||||
stop_binary_process "$port"
|
||||
success "二进制已停止"
|
||||
;;
|
||||
status)
|
||||
local args=()
|
||||
load_binary_args args
|
||||
local port
|
||||
port=$(binary_listen_port "${args[@]}")
|
||||
info "监听端口: $port"
|
||||
if [ -f "$BINARY_PID_FILE" ]; then
|
||||
local pid
|
||||
pid=$(cat "$BINARY_PID_FILE" 2>/dev/null || echo "")
|
||||
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
||||
success "进程运行中 (PID: $pid)"
|
||||
else
|
||||
warning "PID 文件存在但进程未运行"
|
||||
fi
|
||||
else
|
||||
warning "未找到 PID 文件"
|
||||
fi
|
||||
if curl -sf "http://localhost:${port}/version" > /dev/null 2>&1; then
|
||||
success "HTTP 就绪: http://localhost:${port}/version"
|
||||
else
|
||||
warning "HTTP 未响应"
|
||||
fi
|
||||
;;
|
||||
help|--help|-h)
|
||||
echo "独立二进制命令:"
|
||||
echo " ./run.sh binary upgrade [--port 8080 --db-driver sqlite] 停服→清旧→重编译→启动"
|
||||
echo " ./run.sh binary start [args...] 后台启动(参数会持久化)"
|
||||
echo " ./run.sh binary stop [port] 停止进程"
|
||||
echo " ./run.sh binary status 查看状态"
|
||||
echo " ./run.sh binary [--port 8080 ...] 前台运行(开发调试)"
|
||||
;;
|
||||
run|*)
|
||||
cd "$SCRIPT_DIR/$BACKEND_DIR"
|
||||
if [ ! -f "$STANDALONE_BIN" ]; then
|
||||
info "二进制不存在,先编译..."
|
||||
build_standalone_binary || exit 1
|
||||
fi
|
||||
banner "========== 前台启动独立二进制 =========="
|
||||
mkdir -p data logs uploads
|
||||
if [ $# -gt 0 ]; then
|
||||
save_binary_args "$@"
|
||||
fi
|
||||
./"$STANDALONE_BIN" "$@"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ============================================================
|
||||
@@ -553,6 +774,7 @@ KUBERNETES_NAMESPACE="devops"
|
||||
KUBERNETES_MANIFEST_DIR="$SCRIPT_DIR/deploy/kubernetes"
|
||||
KUBERNETES_IMAGE="aiops:embed"
|
||||
KUBERNETES_NODE_PORT=30080
|
||||
KUBERNETES_BUILT_IMAGE=""
|
||||
|
||||
# 检测 kubectl 和 Docker
|
||||
check_kubernetes_deps() {
|
||||
@@ -592,34 +814,52 @@ load_image_to_cluster() {
|
||||
warning "如集群无法拉取镜像,请手动推送: docker push <registry>/$image"
|
||||
}
|
||||
|
||||
# Kubernetes 构建镜像
|
||||
# Kubernetes 构建镜像(upgrade 时无缓存 + 时间戳 tag 避免旧层残留)// Logan.Li
|
||||
cmd_kubernetes_build() {
|
||||
local no_cache=${1:-0}
|
||||
if ! command -v docker &>/dev/null; then
|
||||
error "Docker 未安装"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
banner "========== 构建 embed 镜像 =========="
|
||||
info "镜像: $KUBERNETES_IMAGE"
|
||||
clean_frontend_artifacts
|
||||
clean_embed_static
|
||||
|
||||
# 版本信息
|
||||
local version=$(git describe --tags --abbrev=0 2>/dev/null || echo "dev")
|
||||
local build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
local version
|
||||
version=$(git describe --tags --abbrev=0 2>/dev/null || echo "dev")
|
||||
local build_time
|
||||
build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
local image_tag
|
||||
image_tag="${KUBERNETES_IMAGE}-$(date +%Y%m%d%H%M%S)"
|
||||
info "镜像: $KUBERNETES_IMAGE (+ $image_tag)"
|
||||
|
||||
local build_args=(
|
||||
-f Dockerfile.embed
|
||||
--build-arg VERSION="$version"
|
||||
--build-arg BUILD_TIME="$build_time"
|
||||
-t "$KUBERNETES_IMAGE"
|
||||
-t "$image_tag"
|
||||
)
|
||||
if [ "$no_cache" -eq 1 ]; then
|
||||
build_args+=(--no-cache --pull)
|
||||
info "无缓存全量构建 (--no-cache --pull)"
|
||||
fi
|
||||
build_args+=(.)
|
||||
|
||||
info "构建中(前端 + 后端 embed)..."
|
||||
docker build -f Dockerfile.embed \
|
||||
--build-arg VERSION="$version" \
|
||||
--build-arg BUILD_TIME="$build_time" \
|
||||
-t "$KUBERNETES_IMAGE" . || {
|
||||
docker build "${build_args[@]}" || {
|
||||
error "镜像构建失败"
|
||||
exit 1
|
||||
}
|
||||
|
||||
local img_size=$(docker images "$KUBERNETES_IMAGE" --format "{{.Size}}" | head -1)
|
||||
local img_size
|
||||
img_size=$(docker images "$KUBERNETES_IMAGE" --format "{{.Size}}" | head -1)
|
||||
success "镜像构建完成: $KUBERNETES_IMAGE ($img_size)"
|
||||
|
||||
# 加载到本地集群
|
||||
load_image_to_cluster "$KUBERNETES_IMAGE"
|
||||
load_image_to_cluster "$image_tag"
|
||||
KUBERNETES_BUILT_IMAGE="$image_tag"
|
||||
}
|
||||
|
||||
# Kubernetes 部署
|
||||
@@ -678,10 +918,12 @@ cmd_kubernetes() {
|
||||
upgrade|update)
|
||||
check_kubernetes_deps
|
||||
banner "========== Kubernetes 滚动更新 =========="
|
||||
cmd_kubernetes_build
|
||||
info "触发滚动更新..."
|
||||
kubectl -n "$KUBERNETES_NAMESPACE" rollout restart deployment/aiops
|
||||
cmd_kubernetes_build 1
|
||||
info "更新 Deployment 镜像: $KUBERNETES_BUILT_IMAGE"
|
||||
kubectl -n "$KUBERNETES_NAMESPACE" set image deployment/aiops aiops="$KUBERNETES_BUILT_IMAGE" --record
|
||||
kubectl -n "$KUBERNETES_NAMESPACE" rollout status deployment/aiops --timeout=180s
|
||||
info "清理悬空镜像..."
|
||||
docker image prune -f 2>/dev/null || true
|
||||
success "滚动更新完成"
|
||||
;;
|
||||
|
||||
@@ -812,7 +1054,9 @@ cmd_help() {
|
||||
echo " ./run.sh logs 查看实时日志"
|
||||
echo ""
|
||||
echo -e " ${CYAN}Docker 容器部署${NC}"
|
||||
echo " ./run.sh docker up 构建并启动所有容器 (MySQL+Redis+Nginx)"
|
||||
echo " ./run.sh docker up 增量构建 + 强制重建容器"
|
||||
echo " ./run.sh docker up fresh 无缓存全量重建并启动"
|
||||
echo " ./run.sh docker upgrade 同 up(升级别名)"
|
||||
echo " ./run.sh docker down 停止并移除容器"
|
||||
echo " ./run.sh docker build 仅构建镜像"
|
||||
echo " ./run.sh docker restart 重启容器"
|
||||
@@ -834,7 +1078,9 @@ cmd_help() {
|
||||
echo ""
|
||||
echo -e " ${YELLOW}编译 & 独立二进制${NC}"
|
||||
echo " ./run.sh build 编译独立二进制 ./$BACKEND_DIR/$STANDALONE_BIN"
|
||||
echo " ./run.sh binary 编译+启动独立二进制"
|
||||
echo " ./run.sh binary upgrade 停服→清旧→重编译→后台启动(生产升级)"
|
||||
echo " ./run.sh binary start|stop|status 进程管理"
|
||||
echo " ./run.sh binary [args] 前台启动(调试)"
|
||||
echo " ./run.sh build agent 交叉编译 Agent (amd64+arm64)"
|
||||
echo " ./run.sh build frontend 构建前端生产包"
|
||||
echo ""
|
||||
|
||||
Reference in new issue
Block a user