refactor: shared 共享库统一管理,快照比对避免重复上传;所有 Next.js 站点自动受益
This commit is contained in:
parent
df27929294
commit
312c7ff681
63
deploy-ai.sh
63
deploy-ai.sh
|
|
@ -226,12 +226,60 @@ ENVEOF
|
|||
SNAPSHOT_FILE="/tmp/.snapshot.${SITE}.md5"
|
||||
BUILD_START=$(date +%s)
|
||||
|
||||
# ============================================================
|
||||
# 同步 shared 共享库(快照比对,无变化跳过)
|
||||
# ============================================================
|
||||
SHARED_SNAPSHOT="/tmp/.snapshot.shared.md5"
|
||||
SHARED_LOCAL="/Users/niuniu/programs/docker/shared"
|
||||
SHARED_REMOTE="/root/docker/shared"
|
||||
|
||||
sync_shared() {
|
||||
# 统一管理 /root/docker/shared/,各站点通过 shared -> ../shared 符号链接自动解析
|
||||
|
||||
info "检查 shared 共享库..."
|
||||
local local_md5
|
||||
local_md5=$(find "$SHARED_LOCAL" \
|
||||
-not -path '*/node_modules/*' \
|
||||
-not -path '*/.git/*' \
|
||||
-not -name '._*' \
|
||||
-type f \
|
||||
-exec md5 -q {} \; 2>/dev/null \
|
||||
| sort \
|
||||
| md5 -q)
|
||||
|
||||
local prev_md5
|
||||
prev_md5=$(ssh txjp "cat ${SHARED_SNAPSHOT} 2>/dev/null" 2>/dev/null || echo "")
|
||||
|
||||
if [[ "$prev_md5" == "$local_md5" ]]; then
|
||||
# shared 无变化,仅确保目录存在(防止首次部署或手动清理后死链接)
|
||||
ssh txjp "test -d ${SHARED_REMOTE}/lib || (mkdir -p ${SHARED_REMOTE} && echo 'shared 目录异常但快照存在,已恢复空目录')" 2>/dev/null
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ -z "$prev_md5" ]]; then
|
||||
info "shared 首次部署,上传..."
|
||||
else
|
||||
info "shared 有变化,上传..."
|
||||
fi
|
||||
|
||||
COPYFILE_DISABLE=1 tar czf /tmp/shared-deploy.tar.gz -C /Users/niuniu/programs/docker \
|
||||
--exclude='node_modules' --exclude='.git' --exclude='._*' shared/ 2>/dev/null
|
||||
scp /tmp/shared-deploy.tar.gz txjp:/tmp/shared-deploy.tar.gz
|
||||
ssh txjp "rm -rf ${SHARED_REMOTE} && mkdir -p ${SHARED_REMOTE} && \
|
||||
tar xzf /tmp/shared-deploy.tar.gz -C /root/docker/ && \
|
||||
echo '${local_md5}' > ${SHARED_SNAPSHOT}"
|
||||
log "shared 已同步到 ${SHARED_REMOTE}"
|
||||
}
|
||||
|
||||
build_on_server() {
|
||||
local extra_env="${1:-}"
|
||||
|
||||
# 1. 计算源码快照
|
||||
# 0. 同步 shared 共享库(所有使用 @shared 的站点自动受益)
|
||||
sync_shared
|
||||
|
||||
# 1. 计算源码快照(含 shared,确保 shared 变化也触发重构建)
|
||||
log "检查源码是否有变化..."
|
||||
local_md5=$(find "$LOCAL_DIR" \
|
||||
local_md5=$( (find "$LOCAL_DIR" \
|
||||
-not -path '*/node_modules/*' \
|
||||
-not -path '*/.next/*' \
|
||||
-not -path '*/out/*' \
|
||||
|
|
@ -242,7 +290,13 @@ build_on_server() {
|
|||
-not -path '*/.git/*' \
|
||||
-not -name '._*' \
|
||||
-type f \
|
||||
-exec md5 -q {} \; \
|
||||
-exec md5 -q {} \; ; \
|
||||
find "$SHARED_LOCAL" \
|
||||
-not -path '*/node_modules/*' \
|
||||
-not -path '*/.git/*' \
|
||||
-not -name '._*' \
|
||||
-type f \
|
||||
-exec md5 -q {} \; 2>/dev/null) \
|
||||
| sort \
|
||||
| md5 -q)
|
||||
echo " 源码快照: ${local_md5}"
|
||||
|
|
@ -414,7 +468,8 @@ build_on_server() {
|
|||
|
||||
# 7. 清理构建产生的悬空镜像和缓存(根据磁盘使用率动态调整)
|
||||
log "清理构建缓存..."
|
||||
ssh txjp "docker image prune -f --filter 'label=com.docker.compose.project=${SITE}-ai' 2>/dev/null || true"
|
||||
# 清理悬空镜像(无标签或未被引用的中间层)
|
||||
ssh txjp "docker image prune -f 2>/dev/null || true"
|
||||
|
||||
# 根据磁盘使用率动态调整构建缓存清理策略
|
||||
DISK_USAGE=$(ssh txjp "df / --output=pcent | tail -1 | tr -d ' %'" 2>/dev/null || echo "50")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
#!/bin/bash
|
||||
# deploy-monitor.sh — 部署 monitor-ai 到云服务器
|
||||
# 用法: bash deploy-monitor.sh [--remote --host <IP>] [--dev]
|
||||
set -e
|
||||
|
||||
MODE="${1:-local}"
|
||||
REMOTE_HOST=""
|
||||
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
MONITOR_DIR="$PROJECT_DIR/monitor-ai"
|
||||
SHARED_DIR="$PROJECT_DIR/shared"
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# 解析参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--remote) MODE="remote"; shift ;;
|
||||
--host) REMOTE_HOST="$2"; shift 2 ;;
|
||||
--dev) MODE="dev"; shift ;;
|
||||
*) shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo "=== deploy-monitor.sh === Mode: $MODE ==="
|
||||
|
||||
# 打包源码
|
||||
echo "[1/5] 打包源码..."
|
||||
TARBALL="/tmp/monitor-ai-${TIMESTAMP}.tar.gz"
|
||||
cd "$PROJECT_DIR"
|
||||
tar czf "$TARBALL" --exclude='node_modules' --exclude='.next' --exclude='data/*.db' \
|
||||
shared/lib/ monitor-ai/
|
||||
|
||||
echo "[2/5] 上传..."
|
||||
if [ "$MODE" = "remote" ]; then
|
||||
if [ -z "$REMOTE_HOST" ]; then
|
||||
echo "Error: --remote 模式需要 --host <IP>"
|
||||
exit 1
|
||||
fi
|
||||
ssh "$REMOTE_HOST" "mkdir -p /root/docker"
|
||||
scp "$TARBALL" "$REMOTE_HOST:/root/docker/"
|
||||
ssh "$REMOTE_HOST" "cd /root/docker && tar xzf monitor-ai-${TIMESTAMP}.tar.gz && rm monitor-ai-${TIMESTAMP}.tar.gz"
|
||||
else
|
||||
# local 模式: 部署到当前服务器的 /root/docker/
|
||||
sudo mkdir -p /root/docker
|
||||
sudo cp "$TARBALL" /root/docker/
|
||||
cd /root/docker
|
||||
sudo tar xzf "monitor-ai-${TIMESTAMP}.tar.gz"
|
||||
sudo rm "monitor-ai-${TIMESTAMP}.tar.gz"
|
||||
fi
|
||||
|
||||
echo "[3/5] 构建..."
|
||||
if [ "$MODE" = "remote" ]; then
|
||||
ssh "$REMOTE_HOST" "cd /root/docker/monitor-ai && npm install && npm run build"
|
||||
else
|
||||
cd /root/docker/monitor-ai
|
||||
sudo npm install
|
||||
sudo npm run build
|
||||
fi
|
||||
|
||||
echo "[4/5] 配置首次部署..."
|
||||
if [ "$MODE" = "remote" ]; then
|
||||
# 生成密钥
|
||||
OIDC_SECRET=$(openssl rand -hex 32)
|
||||
LOCALADMIN_PWD=$(openssl rand -hex 16)
|
||||
ssh "$REMOTE_HOST" "cd /root/docker/monitor-ai && \
|
||||
echo 'NODE_ENV=production' > .env && \
|
||||
echo 'DATABASE_PATH=/data/monitor.db' >> .env && \
|
||||
echo 'MONITOR_MODE=local' >> .env && \
|
||||
echo 'AUTHELIA_URL=https://sso.tlyq.ai' >> .env && \
|
||||
echo 'OIDC_CLIENT_ID=monitor-oidc' >> .env && \
|
||||
echo 'OIDC_CLIENT_SECRET=${OIDC_SECRET}' >> .env && \
|
||||
echo 'OIDC_REDIRECT_URI=https://monitor.tlyq.ai/api/auth/callback' >> .env && \
|
||||
echo 'JWT_SECRET=<与全站一致>' >> .env && \
|
||||
echo 'COOKIE_DOMAIN=.tlyq.ai' >> .env && \
|
||||
echo 'LDAP_URL=ldap://ldap-ai:3890' >> .env && \
|
||||
echo 'LOCALADMIN_PASSWORD=${LOCALADMIN_PWD}' >> .env && \
|
||||
echo 'NODE_TLS_REJECT_UNAUTHORIZED=0' >> .env"
|
||||
fi
|
||||
|
||||
echo "[5/5] 启动容器..."
|
||||
if [ "$MODE" = "remote" ]; then
|
||||
ssh "$REMOTE_HOST" "cd /root/docker/monitor-ai && docker compose up -d --build"
|
||||
else
|
||||
cd /root/docker/monitor-ai
|
||||
sudo docker compose up -d --build
|
||||
fi
|
||||
|
||||
echo "=== 部署完成 ==="
|
||||
echo "monitor-ai: https://monitor.tlyq.ai"
|
||||
echo "健康检查: curl https://monitor.tlyq.ai/api/health"
|
||||
Loading…
Reference in New Issue