docs: 添加 README、Release 模板、docker-compose 编排、构建发布脚本

This commit is contained in:
2026-05-17 20:05:45 +08:00
parent 389df53d2d
commit 17b40cea7b
5 changed files with 717 additions and 52 deletions

245
README.md Normal file
View File

@@ -0,0 +1,245 @@
# CloudSearch · 自托管云盘资源搜索引擎
**CloudSearch** 是一个自托管的网盘资源搜索引擎。支持多网盘夸克、百度、阿里云盘等Cookie 接入、关键词搜索、一键转存、多通道消息推送、每日数据汇报。
> 🏷️ 当前版本:**v0.3.32** · 活跃开发中
> 🔒 私有项目 — [Gitea 镜像](https://gitea.timxx.cn/admin/CloudSearch)
---
## ✨ 主要特性
- 🔍 **多源搜索** — 聚合 PanSou + 内置搜索引擎,毫秒级返回
- ☁️ **多云盘接入** — 支持夸克、百度网盘、阿里云盘、115、UC、迅雷、天翼云、PikPak、123 云盘
- 📦 **一键转存** — 搜索结果直接转存到已连接的网盘
- 📊 **管理面板** — 网盘管理、搜索统计、转存记录、系统配置
- 🔔 **14 通道通知** — 飞书/Lark、Telegram、钉钉、企业微信、Discord、Bark、Server酱、PushPlus、Gotify、ntfy、SMTP 邮件、Qmsg酱、自定义 Webhook
- 📈 **每日汇报** — 定时统计搜索/转存/用户数据,自动推送到通知通道
- 🧹 **自动清理** — Cookie 到期检测、空间自动清理、关键词审核
- 🎬 **TMDB 增强** — 搜索结果自动匹配影视元数据(海报、评分、简介)
---
## 📋 前置要求
| 软件 | 最低版本 | 说明 |
|------|---------|------|
| Docker | 24.0+ | 构建和运行容器 |
| Docker Compose | v2.20+ | 编排多服务 |
| Git | 2.40+ | 克隆仓库 |
---
## 🚀 快速部署3 步)
### 1. 克隆仓库
```bash
git clone https://gitea.timxx.cn/admin/CloudSearch.git
cd CloudSearch
```
### 2. 配置环境变量
```bash
cp docker-compose.env .env
# 编辑 .env修改以下必填项
# JWT_SECRET — JWT 签名密钥生成openssl rand -hex 32
# ADMIN_PASSWORD — 管理后台登录密码
# CORS_ORIGIN — 前端访问域名(如 http://your-domain.com
# REDIS_URL — Redis 连接地址
# PANSOU_AUTH_TOKEN — PanSou 搜索 Token可选
```
<details>
<summary>📋 完整环境变量参考</summary>
| 变量 | 默认值 | 必填 | 说明 |
|------|--------|------|------|
| `PORT` | `9527` | | 服务端口 |
| `NODE_ENV` | `production` | | 运行环境 |
| `TZ` | `Asia/Shanghai` | | 时区 |
| `JWT_SECRET` | — | ✅ | JWT 签名密钥 |
| `ADMIN_USERNAME` | `admin` | | 管理员用户名 |
| `ADMIN_PASSWORD` | — | ✅ | 管理员密码 |
| `CORS_ORIGIN` | — | ✅ | CORS 允许的域名 |
| `COOKIE_ENCRYPTION_KEY` | — | | Cookie 加密密钥(生产环境建议设置) |
| `DB_PATH` | `/data/database.sqlite` | | SQLite 数据库路径 |
| `REDIS_URL` | — | ✅ | Redis 连接(格式 `redis://[:password@]host:port` |
| `PANSOU_URL` | `http://pansou:80` | | PanSou 搜索服务地址 |
| `PANSOU_AUTH_TOKEN` | — | | PanSou 鉴权 Token |
| `VALIDATION_CONCURRENCY` | `10` | | 网盘并发校验数 |
| `VALIDATION_TIMEOUT` | `5000` | | 单次校验超时(ms) |
| `CACHE_TTL_VALID` | `14400` | | 有效结果缓存(秒) |
| `CACHE_TTL_INVALID` | `3600` | | 无效结果缓存(秒) |
| `LOG_LEVEL` | `info` | | 日志级别debug/info/warn/error |
| `UPLOAD_DIR` | `/app/uploads` | | 上传文件目录 |
| `APP_VERSION_FILE` | `/app/VERSION` | | 版本文件路径 |
</details>
### 3. 启动服务
```bash
docker compose up -d
```
访问 `http://localhost:9527` — 管理面板:`http://localhost:9527/admin`
---
## 📦 服务架构
```
┌─────────────────────────────────────────────────────┐
│ Nginx / OpenResty │
│ (反向代理 + HTTPS) │
├─────────────────────────────────────────────────────┤
│ CloudSearch_App (:9527) CloudSearch_PanSou (:80) │
│ Node.js + Express + TS 第三方搜索聚合服务 │
│ ┌─────────────────────┐ │
│ │ 前端 (Vue 3 + Vite) │ │
│ │ 后端 (Express API) │ │
│ │ SQLite + Redis │ │
│ │ Chromium (Playwright)│ │
│ └─────────────────────┘ │
├─────────────────────────────────────────────────────┤
│ Redis (:6379) │
│ 缓存 + 会话 │
└─────────────────────────────────────────────────────┘
```
| 容器 | 镜像 | 端口 | 说明 |
|------|------|------|------|
| `CloudSearch_App` | `cloudsearch-app:latest` (自构建) | `9527` | 主服务 |
| `CloudSearch_PanSou` | `ghcr.io/fish2018/pansou-web:latest` | `80` (内部) | 搜索聚合 |
| Redis | `redis:7-alpine` | `6379` (内部) | 缓存 |
---
## 🔄 升级指南
### 方案 A拉取新镜像推荐生产环境
```bash
# 拉取最新版本
docker pull gitea.timxx.cn/admin/cloudsearch:v0.3.32
# 更新 .env 中的镜像标签或使用 latest
docker compose up -d app
```
### 方案 B从源码重新构建
```bash
git pull origin master
./build.sh # 读取 VERSION 构建新镜像
docker compose up -d app
```
> 升级后验证:`curl -s http://localhost:9527/health | jq .version`
---
## 🛠️ 常用命令
```bash
# 查看服务状态
docker compose ps
# 查看日志
docker compose logs -f app # 主服务实时日志
docker compose logs --tail=100 app # 最近100行
# 进入容器
docker compose exec app sh
# 重启服务
docker compose restart app
# 健康检查
curl http://localhost:9527/health
# 查看版本
curl -s http://localhost:9527/health | jq .version
```
---
## 📁 目录结构
```
CloudSearch/
├── VERSION # 🏷️ 当前版本号(唯一真相来源)
├── build.sh # 🔨 构建 Docker 镜像
├── docker-compose.yml # 🐳 服务编排
├── docker-compose.env # 📋 环境变量模板
├── .env # 🔐 本地环境变量Git 忽略)
├── source_clean/ # 🧩 主应用
│ ├── Dockerfile # 多阶段构建node:20-alpine
│ ├── package.json # Node.js 依赖
│ ├── tsconfig.json
│ ├── src/ # 后端 TypeScript 源码
│ │ ├── main.ts # 入口
│ │ ├── config/ # 配置管理
│ │ ├── routes/ # API 路由
│ │ ├── cloud/ # 云盘驱动quark/baidu/aliyun...
│ │ ├── search/ # 搜索服务
│ │ ├── database/ # SQLite 数据库
│ │ ├── services/ # 业务逻辑
│ │ └── middleware/ # 中间件
│ ├── frontend-src/ # 🎨 Vue 3 前端源码
│ │ ├── src/pages/ # 页面组件
│ │ ├── src/api/ # API 封装
│ │ ├── vite.config.ts
│ │ └── package.json
│ └── frontend/ # 📦 编译后的静态资源
├── icons/ # 🖼️ 云盘品牌图标
└── uploads/ # 📤 上传文件
```
---
## 🏗️ 开发指南
### 后端开发
```bash
cd source_clean
npm install
npm run dev # tsx watch热重载
```
### 前端开发
```bash
cd source_clean/frontend-src
npm install
npm run dev # Vite 开发服务器
```
### 构建部署
```bash
# 完整构建流程
./build.sh # 构建 Docker 镜像
docker compose up -d app # 部署
# 仅前端修改(跳过 Docker 重建)
cd source_clean/frontend-src && npm run build
# 将 dist/ 复制到 source_clean/frontend/,重启容器
```
---
## 🔗 相关链接
- 📦 Gitea 镜像:[gitea.timxx.cn/admin/CloudSearch](https://gitea.timxx.cn/admin/CloudSearch)
- 🐳 容器注册表:`gitea.timxx.cn/admin/cloudsearch`
- 📝 版本规则:`X.Y.Z` — patch 每次任务 +0.0.1minor 每轮测试稳定 +0.1.0
---
## 📄 License
私有项目 — 保留所有权利。

83
RELEASE_TEMPLATE.md Normal file
View File

@@ -0,0 +1,83 @@
# 🏷️ vX.Y.Z — YYYY-MM-DD
> **镜像**: `gitea.timxx.cn/admin/cloudsearch:vX.Y.Z`
> **Commit**: `abc1234`
> **构建**: `./build.sh` → Docker 多阶段构建 (node:20-alpine)
---
## ✨ 新增功能
-
---
## 🐛 问题修复
-
---
## 💥 破坏性变更
>
---
## ⚠️ 升级注意事项
### 环境变量变更
> 本次无需修改 `.env`
```diff
# 如需新增/修改环境变量:
# + NEW_VAR=value
# - OLD_VAR=value → NEW_VAR=value
```
### 数据库迁移
> 本次无需手动迁移
```sql
-- 如需执行 SQL请先在 staging 验证):
-- ALTER TABLE xxx ADD COLUMN yyy TEXT DEFAULT '';
```
### 升级步骤
```bash
# 1. 拉取新镜像
docker pull gitea.timxx.cn/admin/cloudsearch:vX.Y.Z
# 2. 更新 docker-compose.yml 中的镜像标签(或使用 latest
# image: gitea.timxx.cn/admin/cloudsearch:vX.Y.Z
# 3. 重新部署
docker compose up -d app
# 4. 验证
curl -s http://localhost:9527/health | jq .version
# → "X.Y.Z"
```
---
## 📋 完整 Changelog
<!-- 用 git log 生成:
git log v0.3.31..v0.3.32 --oneline --no-merges
-->
```
abc1234 feat: xxx
def5678 fix: yyy
```
---
## 🔗 相关
- Gitea: https://gitea.timxx.cn/admin/CloudSearch
- 版本规则: Patch 每次任务 +0.0.1 · Minor 每轮稳定 +0.1.0 · Major 需确认

157
RELEASE_WORKFLOW.md Normal file
View File

@@ -0,0 +1,157 @@
# CloudSearch · 版本发布操作流程
## 🗺️ 概述
CloudSearch 使用 **VERSION 文件** 作为版本号的唯一真相来源。每次发布包含三个步骤:构建镜像 → 推送仓库 → 创建 Release。
---
## 🔢 版本规则
| 类型 | 增量 | 触发条件 |
|------|------|---------|
| **Patch** | `+0.0.1` | 每次完成任务组后 |
| **Minor** | `+0.1.0` | 用户说"测试没问题可以上线了" |
| **Major** | `1.0.0` | 完整流程验证接近完美(需先确认) |
示例:`0.3.31 → 0.3.32` (patch) · `0.3.x → 0.4.0` (minor)
---
## 📋 手动发布流程
### 方式 A一键脚本推荐
```bash
# 1. 登录私有仓库
docker login gitea.timxx.cn
# 2. 执行发布(自动读取 VERSION 或手动指定)
chmod +x scripts/build-and-push.sh
./scripts/build-and-push.sh v0.3.32
```
### 方式 B分步执行
```bash
# 1. 更新版本号
echo "0.3.32" > VERSION
# 2. 构建镜像
cd source_clean
docker build -t cloudsearch-app:v0.3.32 -t cloudsearch-app:latest .
# 3. 标记并推送
docker tag cloudsearch-app:latest gitea.timxx.cn/admin/cloudsearch:v0.3.32
docker tag cloudsearch-app:latest gitea.timxx.cn/admin/cloudsearch:latest
docker push gitea.timxx.cn/admin/cloudsearch:v0.3.32
docker push gitea.timxx.cn/admin/cloudsearch:latest
# 4. Git 标签
git add VERSION && git commit -m "release: v0.3.32"
git tag -a v0.3.32 -m "Release v0.3.32"
git push origin master --tags
```
---
## 📝 Release 说明编写
每次发布在 Gitea 上创建 Release使用 `RELEASE_TEMPLATE.md` 模板,填写以下段落:
1. **版本号与发布日期**
2. **新增功能** — 列出新加的特性
3. **问题修复** — 列出修复的 bug
4. **破坏性变更** — 标注不兼容的 API/配置变更
5. **升级注意事项**`.env` 变更、数据库迁移 SQL
6. **Docker 镜像地址** — 本次发布的完整 tag
### 快速生成 Changelog
```bash
# 从上次发布到现在的提交记录
git log v0.3.31..v0.3.32 --oneline --no-merges
```
---
## 🤖 CI 自动化思路(可选参考)
### Gitea Actions 示例
```yaml
# .gitea/workflows/release.yml
name: Build and Release
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 获取版本号
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: 构建镜像
run: |
docker build -t cloudsearch-app:${{ steps.version.outputs.VERSION }} \
-f source_clean/Dockerfile source_clean/
- name: 登录私有仓库
run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login gitea.timxx.cn -u admin --password-stdin
- name: 推送镜像
run: |
docker tag cloudsearch-app:${{ steps.version.outputs.VERSION }} \
gitea.timxx.cn/admin/cloudsearch:v${{ steps.version.outputs.VERSION }}
docker tag cloudsearch-app:${{ steps.version.outputs.VERSION }} \
gitea.timxx.cn/admin/cloudsearch:latest
docker push gitea.timxx.cn/admin/cloudsearch:v${{ steps.version.outputs.VERSION }}
docker push gitea.timxx.cn/admin/cloudsearch:latest
- name: 创建 Release
uses: actions/gitea-release@v1
with:
tag: v${{ steps.version.outputs.VERSION }}
title: v${{ steps.version.outputs.VERSION }}
body: |
查看 RELEASE_NOTES.md 了解完整变更。
token: ${{ secrets.GITEA_TOKEN }}
```
---
## 🔧 生产部署触发
镜像推送成功后,生产环境执行:
```bash
# 方式1拉取新镜像并重建
docker pull gitea.timxx.cn/admin/cloudsearch:latest
docker compose up -d app
# 方式2指定版本
docker pull gitea.timxx.cn/admin/cloudsearch:v0.3.32
# 修改 docker-compose.yml 中的 image 标签为 :v0.3.32
docker compose up -d app
# 验证
curl -s http://localhost:9527/health | jq .version
# → "0.3.32"
```
---
## ⚠️ 注意事项
- **VERSION 文件是唯一真相来源** — 所有工具build.sh、health check、前端都从它读取
- **不要手动修改 `/app/dist/version.js`** — 它是编译产物,重启后丢失
- **`docker restart` 不会拉取新镜像** — 必须 `docker compose up -d` 重建容器
- **推送前先 pull --rebase** — 避免 force push 覆盖历史
- **每 5 次 patch 迭代同步到 Gitea** — 保持镜像仓库与源码一致

View File

@@ -1,24 +1,141 @@
# CloudSearch — single source of truth: ./VERSION
# 注意: 此 compose 用于参考/文档。实际部署使用 docker run 以兼容 1Panel Redis。
# =============================================================================
# CloudSearch · Docker Compose 部署编排
# =============================================================================
#
# 双模式使用:
#
# 开发/测试模式(从源码构建):
# docker compose up -d
#
# 生产模式(使用预构建镜像):
# 1. 注释掉 services.app.build 段
# 2. 取消注释 services.app.image 行
# 3. docker compose up -d
#
# 构建并推送镜像到私有仓库:
# ./scripts/build-and-push.sh v0.3.32
#
# =============================================================================
networks:
cloudsearch-network:
driver: bridge
volumes:
admin-data:
app-data:
external: true
name: cloudsearch_app-data
pansou-data:
app-data: # 主应用数据SQLite 数据库、上传文件)
redis-data: # Redis 数据持久化
pansou-data: # PanSou 缓存
# ── 日志轮转模板 ────────────────────────────────────────────────────────────
x-logging: &default-logging
driver: json-file
options:
max-size: "50m"
max-file: "10"
# ── 服务定义 ────────────────────────────────────────────────────────────────
services:
# ═══════════════════════════════════════════════════════════════════════════
# CloudSearch 主应用 — Node.js + Express + TypeScript
# ═══════════════════════════════════════════════════════════════════════════
app:
container_name: CloudSearch_App
# ┌─ 开发模式:从源码构建 ──────────────────────────────────────────┐
build:
context: ./source_clean
dockerfile: Dockerfile
# └────────────────────────────────────────────────────────────────┘
# ┌─ 生产模式:使用预构建镜像(切换时取消注释下行,注释 build 段)───┐
# image: gitea.timxx.cn/admin/cloudsearch:latest
# image: gitea.timxx.cn/admin/cloudsearch:v0.3.32
# └────────────────────────────────────────────────────────────────┘
ports:
- "${PORT:-9527}:9527"
environment:
# ── 核心 ──
- NODE_ENV=${NODE_ENV:-production}
- PORT=${PORT:-9527}
- TZ=${TZ:-Asia/Shanghai}
# ── 安全 ──
- JWT_SECRET=${JWT_SECRET}
- ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
- ADMIN_PASSWORD=${ADMIN_PASSWORD}
- COOKIE_ENCRYPTION_KEY=${COOKIE_ENCRYPTION_KEY:-}
- CORS_ORIGIN=${CORS_ORIGIN}
# ── 数据库 & 缓存 ──
- DB_PATH=${DB_PATH:-/data/database.sqlite}
- REDIS_URL=${REDIS_URL:-redis://redis:6379}
# ── 搜索服务 ──
- PANSOU_URL=${PANSOU_URL:-http://pansou:80}
- PANSOU_AUTH_TOKEN=${PANSOU_AUTH_TOKEN:-}
# ── 网盘校验 ──
- VALIDATION_CONCURRENCY=${VALIDATION_CONCURRENCY:-10}
- VALIDATION_TIMEOUT=${VALIDATION_TIMEOUT:-5000}
- CACHE_TTL_VALID=${CACHE_TTL_VALID:-14400}
- CACHE_TTL_INVALID=${CACHE_TTL_INVALID:-3600}
# ── 路径 ──
- CHROMIUM_PATH=${CHROMIUM_PATH:-/usr/bin/chromium-browser}
- APP_VERSION_FILE=${APP_VERSION_FILE:-/data/VERSION}
- UPLOAD_DIR=${UPLOAD_DIR:-/app/uploads}
# ── 日志 ──
- LOG_LEVEL=${LOG_LEVEL:-info}
volumes:
- app-data:/data # 数据库
- ./uploads:/app/uploads # 上传文件
- ./VERSION:/app/VERSION # 版本文件
- ./icons:/app/dist/frontend/admin/icons # 云盘图标
depends_on:
redis:
condition: service_healthy
pansou:
condition: service_started
restart: always
networks:
- cloudsearch-network
logging: *default-logging
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:9527/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
# ═══════════════════════════════════════════════════════════════════════════
# Redis — 缓存 & 会话
# ═══════════════════════════════════════════════════════════════════════════
redis:
container_name: CloudSearch_Redis
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis-data:/data
restart: always
networks:
- cloudsearch-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
start_period: 5s
# ═══════════════════════════════════════════════════════════════════════════
# PanSou — 第三方搜索聚合
# ═══════════════════════════════════════════════════════════════════════════
pansou:
container_name: CloudSearch_PanSou
image: ghcr.io/fish2018/pansou-web:latest
@@ -33,48 +150,3 @@ services:
- pansou-data:/app/data
restart: always
logging: *default-logging
app:
container_name: CloudSearch_App
image: cloudsearch-app:latest
ports:
- "9527:9527"
environment:
- NODE_ENV=production
- CORS_ORIGIN=http://jp-cs.timaa.cn
- JWT_SECRET=u-_1wB...JeIg
- ADMIN_PASSWORD=0nL5kL...b25A
- PANSOU_URL=http://pansou:80
- DB_PATH=/data/database.sqlite
- REDIS_URL=redis://:redis_GbR7XZ@1Panel-redis-aDp3:6379
- CLOUDSEARCH_API=http://localhost:9527
- TRANSFER_CONFIG_PATH=/data/transfer_config.json
- TZ=Asia/Shanghai
- APP_VERSION_FILE=/data/VERSION
volumes:
- cloudsearch_app-data:/data
- ./uploads:/app/uploads
- ./VERSION:/app/VERSION
- ./icons:/app/dist/frontend/admin/icons
depends_on:
- pansou
restart: always
networks:
- cloudsearch-network
logging: *default-logging
admin:
container_name: CloudSearch_Admin
image: cloudsearch-admin:v0.1.0
ports:
- "127.0.0.1:9531:9531"
environment:
- ADMIN_PORT=9531
- ADMIN_PASSWORD=0nL5kL...b25A
- ADMIN_DB_PATH=/data/admin_flags.sqlite
volumes:
- admin-data:/data
restart: always
networks:
- cloudsearch-network
logging: *default-logging

108
scripts/build-and-push.sh Executable file
View File

@@ -0,0 +1,108 @@
#!/usr/bin/env bash
# =============================================================================
# CloudSearch · 构建、推送镜像 & 发布 Release
# =============================================================================
#
# 用法:
# ./scripts/build-and-push.sh [版本号]
#
# 示例:
# ./scripts/build-and-push.sh v0.3.32 # 指定版本
# ./scripts/build-and-push.sh # 自动读取 VERSION 文件
#
# 前置要求:
# - Docker 已安装
# - 已登录 Gitea 容器注册表docker login gitea.timxx.cn
# - Git 仓库已配置 remote
#
# =============================================================================
set -euo pipefail
# ── 配置 ────────────────────────────────────────────────────────────────────
REGISTRY="gitea.timxx.cn"
NAMESPACE="admin"
IMAGE_NAME="cloudsearch"
BUILD_DIR="$(cd "$(dirname "$0")/.." && pwd)"
SCRIPTS_DIR="$(cd "$(dirname "$0")" && pwd)"
# ── 版本号 ──────────────────────────────────────────────────────────────────
if [[ -n "${1:-}" ]]; then
VERSION="$1"
# 去掉 v 前缀(如果有),统一格式
VERSION="${VERSION#v}"
else
# 从 VERSION 文件读取
VERSION_FILE="$BUILD_DIR/VERSION"
if [[ ! -f "$VERSION_FILE" ]]; then
echo "❌ VERSION 文件不存在,请指定版本号:$0 vX.Y.Z"
exit 1
fi
VERSION="$(cat "$VERSION_FILE")"
fi
FULL_TAG="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:v${VERSION}"
LATEST_TAG="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:latest"
LOCAL_TAG="cloudsearch-app:v${VERSION}"
echo "═══════════════════════════════════════════════════════════"
echo " CloudSearch 构建 & 发布"
echo " 版本: v${VERSION}"
echo " 镜像: ${FULL_TAG}"
echo "═══════════════════════════════════════════════════════════"
echo ""
# ── 1. 更新 VERSION 文件 ───────────────────────────────────────────────────
echo "📝 [1/5] 更新 VERSION 文件..."
echo "$VERSION" > "$VERSION_FILE"
echo " VERSION → $(cat $VERSION_FILE)"
# ── 2. 构建 Docker 镜像 ─────────────────────────────────────────────────────
echo ""
echo "🔨 [2/5] 构建 Docker 镜像..."
cd "$BUILD_DIR/source_clean"
docker build \
-t "$LOCAL_TAG" \
-t "cloudsearch-app:latest" \
.
echo " ✅ 本地镜像构建完成: $LOCAL_TAG"
# ── 3. 标记镜像 ─────────────────────────────────────────────────────────────
echo ""
echo "🏷️ [3/5] 标记镜像..."
docker tag "cloudsearch-app:latest" "$FULL_TAG"
docker tag "cloudsearch-app:latest" "$LATEST_TAG"
echo " $FULL_TAG"
echo " $LATEST_TAG"
# ── 4. 推送镜像 ─────────────────────────────────────────────────────────────
echo ""
echo "📤 [4/5] 推送镜像到私有仓库..."
docker push "$FULL_TAG"
docker push "$LATEST_TAG"
echo " ✅ 推送完成"
# ── 5. 创建 Git 标签 ───────────────────────────────────────────────────────
echo ""
echo "🏷️ [5/5] 创建 Git 标签..."
cd "$BUILD_DIR"
git add VERSION
git commit -m "release: v${VERSION}" || echo " (无变更,跳过 commit)"
git tag -a "v${VERSION}" -m "Release v${VERSION}"
echo " 标签 v${VERSION} 已创建(稍后 git push --tags"
# ── 完成 ────────────────────────────────────────────────────────────────────
echo ""
echo "═══════════════════════════════════════════════════════════"
echo " ✅ 发布完成!"
echo ""
echo " 推送到远程:"
echo " git push origin master --tags"
echo ""
echo " 生产部署:"
echo " docker pull ${FULL_TAG}"
echo " docker compose up -d app"
echo ""
echo " 验证:"
echo " curl -s http://localhost:9527/health | jq .version"
echo "═══════════════════════════════════════════════════════════"