- migrateCloudConfigs 缺 } 导致 notify_config/cloud_type_uid 嵌套在 promotion_account 内不迁移 - cloud_configs_v2 INSERT/SELECT 缺 cloud_type_uid/cookie_uid 导致数据丢失 - deploy.sh 密码嵌入改成 docker exec -e 传参(防特殊字符注入)
129 lines
4.1 KiB
Bash
Executable File
129 lines
4.1 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
# CloudSearch 一键部署
|
|
# curl -sS https://gitea.timxx.cn/admin/CloudSearch/raw/branch/master/source_clean/deploy.sh | bash
|
|
#
|
|
# 环境变量(可选):
|
|
# CORS_ORIGIN - 域名 (默认自动检测公网IP)
|
|
# ADMIN_PASSWORD - 管理员密码 (留空自动生成)
|
|
# JWT_SECRET - JWT密钥 (留空自动生成)
|
|
# DEPLOY_DIR - 部署目录 (默认 /opt/cloudsearch)
|
|
|
|
REPO_URL="https://gitea.timxx.cn/admin/CloudSearch.git"
|
|
DEPLOY_DIR="${DEPLOY_DIR:-/opt/cloudsearch}"
|
|
|
|
info() { echo "[INFO] $*"; }
|
|
warn() { echo "[WARN] $*"; }
|
|
err() { echo "[ERROR] $*"; }
|
|
|
|
command -v docker &>/dev/null || { err "Docker未安装"; exit 1; }
|
|
|
|
# -- CORS_ORIGIN --
|
|
if [ -z "$CORS_ORIGIN" ]; then
|
|
PUBLIC_IP=$(curl -s --connect-timeout 3 ifconfig.me 2>/dev/null || curl -s --connect-timeout 3 ip.sb 2>/dev/null || echo "")
|
|
if [ -n "$PUBLIC_IP" ]; then
|
|
CORS_ORIGIN="http://${PUBLIC_IP}:9527"
|
|
else
|
|
CORS_ORIGIN="http://localhost:9527"
|
|
fi
|
|
warn "CORS_ORIGIN=$CORS_ORIGIN (自动检测)"
|
|
fi
|
|
|
|
# -- 拉取仓库 --
|
|
info "拉取仓库..."
|
|
if [ -d "$DEPLOY_DIR/.git" ]; then
|
|
cd "$DEPLOY_DIR" && git pull --ff-only origin master 2>/dev/null || true
|
|
else
|
|
rm -rf "$DEPLOY_DIR"
|
|
git clone --depth 1 "$REPO_URL" "$DEPLOY_DIR"
|
|
fi
|
|
cd "$DEPLOY_DIR/source_clean"
|
|
|
|
# -- 切换镜像模式 --
|
|
if grep -q '^ build:' docker-compose.yml 2>/dev/null; then
|
|
info "切换镜像模式..."
|
|
sed -i 's/^ build:/ # build:/' docker-compose.yml
|
|
sed -i 's/^ context:/ # context:/' docker-compose.yml
|
|
sed -i 's/^ dockerfile:/ # dockerfile:/' docker-compose.yml
|
|
sed -i 's|^ # image: gitea.timxx.cn/admin/cloudsearch:latest| image: gitea.timxx.cn/admin/cloudsearch:latest|' docker-compose.yml
|
|
fi
|
|
|
|
# -- 检测 Redis --
|
|
info "检测Redis..."
|
|
EXISTING_REDIS=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -i redis | grep -v CloudSearch | head -1)
|
|
if [ -n "$EXISTING_REDIS" ]; then
|
|
REDIS_URL="redis://${EXISTING_REDIS}:6379"
|
|
info "复用已有Redis: $EXISTING_REDIS"
|
|
else
|
|
REDIS_URL="redis://redis:6379"
|
|
info "使用Compose自带Redis"
|
|
fi
|
|
|
|
# -- 生成密钥 --
|
|
JWT_SECRET="${JWT_SECRET:-$(openssl rand -hex 32)}"
|
|
ADMIN_PASSWORD="${ADMIN_PASSWORD:-$(openssl rand -base64 12 | tr -d '=+/' | head -c 16)}"
|
|
|
|
# -- 生成 .env --
|
|
cat > .env <<ENVEOF
|
|
CORS_ORIGIN=${CORS_ORIGIN}
|
|
JWT_SECRET=${JWT_SECRET}
|
|
ADMIN_PASSWORD=${ADMIN_PASSWORD}
|
|
REDIS_URL=${REDIS_URL}
|
|
LOG_LEVEL=${LOG_LEVEL:-info}
|
|
ENVEOF
|
|
|
|
info "管理员: admin / ${ADMIN_PASSWORD}"
|
|
|
|
# -- 部署 --
|
|
info "拉取镜像..."
|
|
docker compose pull app 2>/dev/null || true
|
|
|
|
info "停止旧服务..."
|
|
docker compose down --remove-orphans 2>/dev/null || true
|
|
|
|
info "启动服务..."
|
|
docker compose up -d
|
|
|
|
# -- 等待就绪 --
|
|
info "等待服务就绪..."
|
|
for i in $(seq 1 20); do
|
|
if curl -s -o /dev/null -w '%{http_code}' http://localhost:9527/health 2>/dev/null | grep -q '200'; then
|
|
break
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
# -- 强制写入管理员密码 --
|
|
info "同步管理员密码..."
|
|
sleep 3
|
|
docker exec -e ADMIN_PASSWORD="$ADMIN_PASSWORD" CloudSearch_App node -e '
|
|
var bcrypt = require("bcryptjs");
|
|
var Database = require("better-sqlite3");
|
|
var db = new Database("/data/database.sqlite");
|
|
var pw = process.env.ADMIN_PASSWORD || ""; var hash = bcrypt.hashSync(pw, 10);
|
|
var existing = db.prepare("SELECT id FROM admins WHERE username = ?").get("admin");
|
|
if (existing) {
|
|
db.prepare("UPDATE admins SET password_hash = ? WHERE username = ?").run(hash, "admin");
|
|
} else {
|
|
db.prepare("INSERT INTO admins (username, password_hash) VALUES (?, ?)").run("admin", hash);
|
|
}
|
|
db.close();
|
|
' 2>/dev/null && info "密码已同步" || warn "密码同步失败,请稍后重试"
|
|
|
|
# -- 验证 --
|
|
if docker compose ps 2>/dev/null | grep -q 'Up'; then
|
|
echo ""
|
|
echo "=============================================="
|
|
echo " CloudSearch 部署完成"
|
|
echo "=============================================="
|
|
docker compose ps
|
|
echo ""
|
|
echo " 管理后台: ${CORS_ORIGIN}/admin/login"
|
|
echo " 用户名: admin"
|
|
echo " 密码: ${ADMIN_PASSWORD}"
|
|
else
|
|
err "启动失败: docker compose logs"
|
|
exit 1
|
|
fi
|