Compare commits

...

14 Commits

Author SHA1 Message Date
yyhuni
e8a5e0cea8 Update README.md 2026-01-17 17:09:49 +08:00
yyhuni
3308908d7a Update README.md 2026-01-16 21:43:08 +08:00
yyhuni
a8402cfffa Update project status in README 2026-01-16 17:56:44 +08:00
yyhuni
dce4e12667 Update README.md 2026-01-16 17:56:26 +08:00
github-actions[bot]
bd1dd2c0d5 chore: bump version to v1.5.8 2026-01-11 19:34:26 +08:00
yyhuni
0b6560ac17 Update README.md 2026-01-10 16:28:30 +08:00
yyhuni
943a4cb960 docs(docker): remove default credentials from startup message
- Remove hardcoded default username and password display from docker startup script
- Remove warning message about changing password after first login
- Improve security by not exposing default credentials in startup output
- Simplifies startup message output for cleaner user experience
2026-01-10 11:21:14 +08:00
yyhuni
eb2d853b76 docs: remove emoji symbols from README for better accessibility
- Remove shield emoji (🛡️) from main title
- Replace emoji prefixes in navigation links with plain text anchors
- Remove emoji icons from section headers (🌐, 📚, , 📦, 🤝, 📧, 🎁, , 🙏, ⚠️, 🌟, 📄)
- Replace emoji status indicators (, ⚠️, 🔍, 💡, ) with plain text equivalents
- Remove emoji bullet points and replace with standard formatting
- Simplify documentation for improved readability and cross-platform compatibility
2026-01-10 11:17:43 +08:00
github-actions[bot]
1184c18b74 chore: bump version to v1.5.7 2026-01-10 03:10:45 +00:00
yyhuni
8a6f1b6f24 feat(engine): add --force-sub flag for selective engine config updates
- Add --force-sub command flag to init_default_engine management command
- Allow updating only sub-engines while preserving user-customized full scan config
- Update docker/scripts/init-data.sh to always update full scan engine configuration
- Change docker/server/start.sh to use --force flag for initial engine setup
- Improve update.sh with better logging functions and formatted output
- Add color-coded log functions (log_step, log_ok, log_info, log_warn, log_error)
- Enhance update.sh UI with better visual formatting and warning messages
- Refactor error messages and user prompts for improved clarity
- This enables safer upgrades by preserving custom full scan configurations while updating sub-engines
2026-01-10 11:04:42 +08:00
yyhuni
255d505aba refactor(scan): remove deprecated amass engine configurations
- Remove amass_passive engine configuration from subdomain discovery defaults
- Remove amass_active engine configuration from subdomain discovery defaults
- Simplify engine configuration by eliminating unused amass-based scanners
- Streamline the default engine template for better maintainability
2026-01-10 10:51:07 +08:00
github-actions[bot]
d06a9bab1f chore: bump version to v1.5.7-dev 2026-01-10 02:48:21 +00:00
yyhuni
6d5c776bf7 chore: improve version detection and update deployment configuration
- Update version detection to support IMAGE_TAG environment variable for Docker containers
- Add fallback mechanism to check multiple version file paths (/app/VERSION and project root)
- Add IMAGE_TAG environment variable to docker-compose.dev.yml and docker-compose.yml
- Fix frontend access URL in start.sh to include correct port (8083)
- Update upgrade warning message in update.sh to recommend fresh installation with latest code
- Improve robustness of version retrieval with better error handling for missing files
2026-01-10 10:41:36 +08:00
github-actions[bot]
bf058dd67b chore: bump version to v1.5.6-dev 2026-01-10 02:33:15 +00:00
11 changed files with 180 additions and 149 deletions

129
README.md
View File

@@ -1,7 +1,7 @@
<h1 align="center">XingRin - 星环</h1>
<p align="center">
<b>🛡️ 攻击面管理平台 (ASM) | 自动化资产发现与漏洞扫描系统</b>
<b>攻击面管理平台 (ASM) | 自动化资产发现与漏洞扫描系统</b>
</p>
<p align="center">
@@ -12,29 +12,28 @@
</p>
<p align="center">
<a href="#-功能特性">功能特性</a> •
<a href="#-全局资产搜索">资产搜索</a> •
<a href="#-快速开始">快速开始</a> •
<a href="#-文档">文档</a> •
<a href="#-反馈与贡献">反馈与贡献</a>
<a href="#功能特性">功能特性</a> •
<a href="#全局资产搜索">资产搜索</a> •
<a href="#快速开始">快速开始</a> •
<a href="#文档">文档</a> •
<a href="#反馈与贡献">反馈与贡献</a>
</p>
<p align="center">
<sub>🔍 关键词: ASM | 攻击面管理 | 漏洞扫描 | 资产发现 | 资产搜索 | Bug Bounty | 渗透测试 | Nuclei | 子域名枚举 | EASM</sub>
<sub>关键词: ASM | 攻击面管理 | 漏洞扫描 | 资产发现 | 资产搜索 | Bug Bounty | 渗透测试 | Nuclei | 子域名枚举 | EASM</sub>
</p>
---
## 🌐 在线 Demo
## 在线 Demo
**[https://xingrin.vercel.app/](https://xingrin.vercel.app/)**
> ⚠️ 仅用于 UI 展示,未接入后端数据库
> 仅用于 UI 展示,未接入后端数据库
---
<p align="center">
<b>🎨 现代化 UI </b>
<b>现代化 UI</b>
</p>
<p align="center">
@@ -44,45 +43,45 @@
<img src="docs/screenshots/quantum-rose.png" alt="Quantum Rose" width="24%">
</p>
## 📚 文档
## 文档
- [📖 技术文档](./docs/README.md) - 技术文档导航(🚧 持续完善中)
- [🚀 快速开始](./docs/quick-start.md) - 一键安装和部署指南
- [🔄 版本管理](./docs/version-management.md) - Git Tag 驱动的自动化版本管理系统
- [📦 Nuclei 模板架构](./docs/nuclei-template-architecture.md) - 模板仓库的存储与同步
- [📖 字典文件架构](./docs/wordlist-architecture.md) - 字典文件的存储与同步
- [🔍 扫描流程架构](./docs/scan-flow-architecture.md) - 完整扫描流程与工具编排
- [技术文档](./docs/README.md) - 技术文档导航(持续完善中)
- [快速开始](./docs/quick-start.md) - 一键安装和部署指南
- [版本管理](./docs/version-management.md) - Git Tag 驱动的自动化版本管理系统
- [Nuclei 模板架构](./docs/nuclei-template-architecture.md) - 模板仓库的存储与同步
- [字典文件架构](./docs/wordlist-architecture.md) - 字典文件的存储与同步
- [扫描流程架构](./docs/scan-flow-architecture.md) - 完整扫描流程与工具编排
---
## 功能特性
## 功能特性
### 扫描能力
| 功能 | 状态 | 工具 | 说明 |
|------|------|------|------|
| 子域名扫描 | | Subfinder, Amass, PureDNS | 被动收集 + 主动爆破,聚合 50+ 数据源 |
| 端口扫描 | | Naabu | 自定义端口范围 |
| 站点发现 | | HTTPX | HTTP 探测,自动获取标题、状态码、技术栈 |
| 指纹识别 | | XingFinger | 2.7W+ 指纹规则,多源指纹库 |
| URL 收集 | | Waymore, Katana | 历史数据 + 主动爬取 |
| 目录扫描 | | FFUF | 高速爆破,智能字典 |
| 漏洞扫描 | | Nuclei, Dalfox | 9000+ POC 模板XSS 检测 |
| 站点截图 | | Playwright | WebP 高压缩存储 |
| 子域名扫描 | 已完成 | Subfinder, Amass, PureDNS | 被动收集 + 主动爆破,聚合 50+ 数据源 |
| 端口扫描 | 已完成 | Naabu | 自定义端口范围 |
| 站点发现 | 已完成 | HTTPX | HTTP 探测,自动获取标题、状态码、技术栈 |
| 指纹识别 | 已完成 | XingFinger | 2.7W+ 指纹规则,多源指纹库 |
| URL 收集 | 已完成 | Waymore, Katana | 历史数据 + 主动爬取 |
| 目录扫描 | 已完成 | FFUF | 高速爆破,智能字典 |
| 漏洞扫描 | 已完成 | Nuclei, Dalfox | 9000+ POC 模板XSS 检测 |
| 站点截图 | 已完成 | Playwright | WebP 高压缩存储 |
### 平台能力
| 功能 | 状态 | 说明 |
|------|------|------|
| 目标管理 | | 多层级组织,支持域名/IP 目标 |
| 资产快照 | | 扫描结果对比,追踪资产变化 |
| 黑名单过滤 | | 全局 + Target 级,支持通配符/CIDR |
| 定时任务 | | Cron 表达式,自动化周期扫描 |
| 分布式扫描 | | 多 Worker 节点,负载感知调度 |
| 全局搜索 | | 表达式语法,多字段组合查询 |
| 通知推送 | | 企业微信、Telegram、Discord |
| API 密钥管理 | | 可视化配置各数据源 API Key |
| 目标管理 | 已完成 | 多层级组织,支持域名/IP 目标 |
| 资产快照 | 已完成 | 扫描结果对比,追踪资产变化 |
| 黑名单过滤 | 已完成 | 全局 + Target 级,支持通配符/CIDR |
| 定时任务 | 已完成 | Cron 表达式,自动化周期扫描 |
| 分布式扫描 | 已完成 | 多 Worker 节点,负载感知调度 |
| 全局搜索 | 已完成 | 表达式语法,多字段组合查询 |
| 通知推送 | 已完成 | 企业微信、Telegram、Discord |
| API 密钥管理 | 已完成 | 可视化配置各数据源 API Key |
### 扫描流程架构
@@ -136,7 +135,7 @@ flowchart LR
详细说明请查看 [扫描流程架构文档](./docs/scan-flow-architecture.md)
### 🖥️ 分布式架构
### 分布式架构
- **多节点扫描** - 支持部署多个 Worker 节点,横向扩展扫描能力
- **本地节点** - 零配置,安装即自动注册本地 Docker Worker
- **远程节点** - SSH 一键部署远程 VPS 作为扫描节点
@@ -181,7 +180,7 @@ flowchart TB
W3 -.心跳上报.-> REDIS
```
### 🔎 全局资产搜索
### 全局资产搜索
- **多类型搜索** - 支持 Website 和 Endpoint 两种资产类型
- **表达式语法** - 支持 `=`(模糊)、`==`(精确)、`!=`(不等于)操作符
- **逻辑组合** - 支持 `&&` (AND) 和 `||` (OR) 逻辑组合
@@ -205,14 +204,14 @@ host="admin" && tech="php" && status=="200"
url="/api/v1" && status!="404"
```
### 📊 可视化界面
### 可视化界面
- **数据统计** - 资产/漏洞统计仪表盘
- **实时通知** - WebSocket 消息推送
- **通知推送** - 实时企业微信tgdiscard消息推送服务
---
## 📦 快速开始
## 快速开始
### 环境要求
@@ -230,11 +229,11 @@ cd xingrin
# 安装并启动(生产模式)
sudo ./install.sh
# 🇨🇳 中国大陆用户推荐使用镜像加速(第三方加速服务可能会失效,不保证长期可用)
# 中国大陆用户推荐使用镜像加速(第三方加速服务可能会失效,不保证长期可用)
sudo ./install.sh --mirror
```
> **💡 --mirror 参数说明**
> **--mirror 参数说明**
> - 自动配置 Docker 镜像加速(国内镜像源)
> - 加速 Git 仓库克隆Nuclei 模板等)
@@ -259,17 +258,17 @@ sudo ./restart.sh
sudo ./uninstall.sh
```
## 🤝 反馈与贡献
## 反馈与贡献
- 💡 **发现 Bug有新想法比如UI设计功能设计等** 欢迎点击右边链接进行提交建议 [Issue](https://github.com/yyhuni/xingrin/issues) 或者公众号私信
- **发现 Bug有新想法比如UI设计功能设计等** 欢迎点击右边链接进行提交建议 [Issue](https://github.com/yyhuni/xingrin/issues) 或者公众号私信
## 📧 联系
## 联系
- 微信公众号: **塔罗安全学苑**
- 微信群去公众号底下的菜单,有个交流群,点击就可以看到了,链接过期可以私信我拉你
<img src="docs/wechat-qrcode.png" alt="微信公众号" width="200">
### 🎁 关注公众号免费领取指纹库
### 关注公众号免费领取指纹库
| 指纹库 | 数量 |
|--------|------|
@@ -278,9 +277,9 @@ sudo ./uninstall.sh
| goby.json | 7,086 |
| FingerprintHub.json | 3,147 |
> 💡 关注公众号回复「指纹」即可获取
> 关注公众号回复「指纹」即可获取
## 赞助支持
## 赞助支持
如果这个项目对你有帮助谢谢请我能喝杯蜜雪冰城你的star和赞助是我免费更新的动力
@@ -289,14 +288,9 @@ sudo ./uninstall.sh
<img src="docs/zfb_pay.jpg" alt="支付宝" width="200">
</p>
### 🙏 感谢以下赞助
| 昵称 | 金额 |
|------|------|
| X闭关中 | ¥88 |
## ⚠️ 免责声明
## 免责声明
**重要:请在使用前仔细阅读**
@@ -311,30 +305,29 @@ sudo ./uninstall.sh
- 遵守所在地区的法律法规
- 承担因滥用产生的一切后果
## 🌟 Star History
## Star History
如果这个项目对你有帮助,请给一个 Star 支持一下!
如果这个项目对你有帮助,请给一个 Star 支持一下!
[![Star History Chart](https://api.star-history.com/svg?repos=yyhuni/xingrin&type=Date)](https://star-history.com/#yyhuni/xingrin&Date)
## 📄 许可证
## 许可证
本项目采用 [GNU General Public License v3.0](LICENSE) 许可证。
### 允许的用途
- 个人学习和研究
- 商业和非商业使用
- 修改和分发
- 专利使用
- 私人使用
- 个人学习和研究
- 商业和非商业使用
- 修改和分发
- 专利使用
- 私人使用
### 义务和限制
- 📋 **开源义务**:分发时必须提供源代码
- 📋 **相同许可**:衍生作品必须使用相同许可证
- 📋 **版权声明**:必须保留原始版权和许可证声明
- **责任免除**:不提供任何担保
- 未经授权的渗透测试
- 任何违法行为
- **开源义务**:分发时必须提供源代码
- **相同许可**:衍生作品必须使用相同许可证
- **版权声明**:必须保留原始版权和许可证声明
- **责任免除**:不提供任何担保
- 未经授权的渗透测试
- 任何违法行为

View File

@@ -1 +1 @@
v1.5.4-dev
v1.5.8

View File

@@ -23,11 +23,26 @@ GITHUB_RELEASES_URL = f"https://github.com/{GITHUB_REPO}/releases"
def get_current_version() -> str:
"""读取当前版本号"""
version_file = Path(__file__).parent.parent.parent.parent.parent / 'VERSION'
try:
return version_file.read_text(encoding='utf-8').strip()
except FileNotFoundError:
return "unknown"
import os
# 方式1从环境变量读取Docker 容器中推荐)
version = os.environ.get('IMAGE_TAG', '')
if version:
return version
# 方式2从文件读取开发环境
possible_paths = [
Path('/app/VERSION'),
Path(__file__).parent.parent.parent.parent.parent / 'VERSION',
]
for path in possible_paths:
try:
return path.read_text(encoding='utf-8').strip()
except (FileNotFoundError, OSError):
continue
return "unknown"
def compare_versions(current: str, latest: str) -> bool:

View File

@@ -2,8 +2,9 @@
初始化默认扫描引擎
用法:
python manage.py init_default_engine # 只创建不存在的引擎(不覆盖已有)
python manage.py init_default_engine --force # 强制覆盖所有引擎配置
python manage.py init_default_engine # 只创建不存在的引擎(不覆盖已有)
python manage.py init_default_engine --force # 强制覆盖所有引擎配置
python manage.py init_default_engine --force-sub # 只覆盖子引擎,保留 full scan
cd /root/my-vulun-scan/docker
docker compose exec server python backend/manage.py init_default_engine --force
@@ -12,6 +13,7 @@
- 读取 engine_config_example.yaml 作为默认配置
- 创建 full scan默认引擎+ 各扫描类型的子引擎
- 默认不覆盖已有配置,加 --force 才会覆盖
- 加 --force-sub 只覆盖子引擎配置,保留用户自定义的 full scan
"""
from django.core.management.base import BaseCommand
@@ -30,11 +32,18 @@ class Command(BaseCommand):
parser.add_argument(
'--force',
action='store_true',
help='强制覆盖已有的引擎配置',
help='强制覆盖已有的引擎配置(包括 full scan 和子引擎)',
)
parser.add_argument(
'--force-sub',
action='store_true',
help='只覆盖子引擎配置,保留 full scan升级时使用',
)
def handle(self, *args, **options):
force = options.get('force', False)
force_sub = options.get('force_sub', False)
# 读取默认配置文件
config_path = Path(__file__).resolve().parent.parent.parent.parent / 'scan' / 'configs' / 'engine_config_example.yaml'
@@ -99,15 +108,22 @@ class Command(BaseCommand):
engine_name = f"{scan_type}"
sub_engine = ScanEngine.objects.filter(name=engine_name).first()
if sub_engine:
if force:
# force 或 force_sub 都会覆盖子引擎
if force or force_sub:
sub_engine.configuration = single_yaml
sub_engine.save()
self.stdout.write(self.style.SUCCESS(f' ✓ 子引擎 {engine_name} 配置已更新 (ID: {sub_engine.id})'))
self.stdout.write(self.style.SUCCESS(
f' ✓ 子引擎 {engine_name} 配置已更新 (ID: {sub_engine.id})'
))
else:
self.stdout.write(self.style.WARNING(f'{engine_name} 已存在,跳过(使用 --force 覆盖)'))
self.stdout.write(self.style.WARNING(
f'{engine_name} 已存在,跳过(使用 --force 覆盖)'
))
else:
sub_engine = ScanEngine.objects.create(
name=engine_name,
configuration=single_yaml,
)
self.stdout.write(self.style.SUCCESS(f' ✓ 子引擎 {engine_name} 已创建 (ID: {sub_engine.id})'))
self.stdout.write(self.style.SUCCESS(
f' ✓ 子引擎 {engine_name} 已创建 (ID: {sub_engine.id})'
))

View File

@@ -44,6 +44,8 @@ services:
restart: always
env_file:
- .env
environment:
- IMAGE_TAG=${IMAGE_TAG:-dev}
ports:
- "8888:8888"
depends_on:

View File

@@ -48,6 +48,8 @@ services:
restart: always
env_file:
- .env
environment:
- IMAGE_TAG=${IMAGE_TAG}
depends_on:
redis:
condition: service_healthy

View File

@@ -83,20 +83,20 @@ if not yaml_path.exists():
print('未找到配置文件,跳过')
exit(0)
new_config = yaml_path.read_text()
# 检查是否已有 full scan 引擎
engine = ScanEngine.objects.filter(name='full scan').first()
if engine:
if not engine.configuration or not engine.configuration.strip():
engine.configuration = yaml_path.read_text()
engine.save(update_fields=['configuration'])
print(f'已初始化引擎配置: {engine.name}')
else:
print(f'引擎已有配置,跳过')
# 直接覆盖为最新配置
engine.configuration = new_config
engine.save(update_fields=['configuration'])
print(f'已更新引擎配置: {engine.name}')
else:
# 创建引擎
engine = ScanEngine.objects.create(
name='full scan',
configuration=yaml_path.read_text(),
configuration=new_config,
)
print(f'已创建引擎: {engine.name}')
"

View File

@@ -10,7 +10,7 @@ python manage.py migrate --noinput
echo " ✓ 数据库迁移完成"
echo " [1.1/3] 初始化默认扫描引擎..."
python manage.py init_default_engine
python manage.py init_default_engine --force
echo " ✓ 默认扫描引擎已就绪"
echo " [1.2/3] 初始化默认目录字典..."

View File

@@ -182,7 +182,7 @@ echo -e "${BOLD}${GREEN}══════════════════
echo ""
echo -e "${BOLD}访问地址${NC}"
if [ "$WITH_FRONTEND" = true ]; then
echo -e " XingRin: ${CYAN}https://${ACCESS_HOST}/${NC}"
echo -e " XingRin: ${CYAN}https://${ACCESS_HOST}:8083/${NC}"
echo -e " ${YELLOW}(HTTP 会自动跳转到 HTTPS)${NC}"
else
echo -e " API: ${CYAN}通过前端或 nginx 访问(后端未暴露 8888${NC}"
@@ -191,8 +191,3 @@ else
echo " cd frontend && pnpm dev"
fi
echo ""
echo -e "${BOLD}默认账号${NC}"
echo " 用户名: admin"
echo " 密码: admin"
echo -e " ${YELLOW}[!] 请首次登录后修改密码${NC}"
echo ""

View File

@@ -58,14 +58,6 @@ subdomain_discovery:
enabled: true
timeout: 600 # 10 minutes (required)
amass_passive:
enabled: true
timeout: 600 # 10 minutes (required)
amass_active:
enabled: true
timeout: 1800 # 30 minutes (required)
sublist3r:
enabled: true
timeout: 900 # 15 minutes (required)

108
update.sh
View File

@@ -21,8 +21,8 @@ cd "$(dirname "$0")"
# 权限检查
if [ "$EUID" -ne 0 ]; then
echo -e "\033[0;31m[错误] 请使用 sudo 运行此脚本\033[0m"
echo -e " 正确用法: \033[1msudo ./update.sh\033[0m"
printf "\033[0;31m 请使用 sudo 运行此脚本\033[0m\n"
printf " 正确用法: \033[1msudo ./update.sh\033[0m\n"
exit 1
fi
@@ -49,9 +49,17 @@ YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
DIM='\033[2m'
BOLD='\033[1m'
NC='\033[0m'
# 日志函数
log_step() { printf "${CYAN}${NC} %s\n" "$1"; }
log_ok() { printf " ${GREEN}${NC} %s\n" "$1"; }
log_info() { printf " ${DIM}${NC} %s\n" "$1"; }
log_warn() { printf " ${YELLOW}!${NC} %s\n" "$1"; }
log_error() { printf "${RED}${NC} %s\n" "$1"; }
# 合并 .env 新配置项(保留用户已有值)
merge_env_config() {
local example_file="docker/.env.example"
@@ -70,58 +78,68 @@ merge_env_config() {
if ! grep -q "^${key}=" "$env_file"; then
printf '%s\n' "$line" >> "$env_file"
echo -e " ${GREEN}+${NC} 新增: $key"
log_info "新增配置: $key"
((new_keys++))
fi
done < "$example_file"
if [ $new_keys -gt 0 ]; then
echo -e " ${GREEN}OK${NC} 已添加 $new_keys 个新配置项"
log_ok "已添加 $new_keys 个新配置项"
else
echo -e " ${GREEN}OK${NC} 配置已是最新"
log_ok "配置已是最新"
fi
}
echo ""
echo -e "${BOLD}${BLUE}╔════════════════════════════════════════╗${NC}"
# 显示标题
printf "\n"
printf "${BOLD}${BLUE}┌────────────────────────────────────────┐${NC}\n"
if [ "$DEV_MODE" = true ]; then
echo -e "${BOLD}${BLUE}║ 开发环境更新(本地构建) ║${NC}"
printf "${BOLD}${BLUE}${NC} ${BOLD}XingRin 系统更新${NC} ${BOLD}${BLUE}${NC}\n"
printf "${BOLD}${BLUE}${NC} ${DIM}开发模式 · 本地构建${NC} ${BOLD}${BLUE}${NC}\n"
else
echo -e "${BOLD}${BLUE}║ 生产环境更新Docker Hub${NC}"
printf "${BOLD}${BLUE}${NC} ${BOLD}XingRin 系统更新${NC} ${BOLD}${BLUE}${NC}\n"
printf "${BOLD}${BLUE}${NC} ${DIM}生产模式 · Docker Hub${NC} ${BOLD}${BLUE}${NC}\n"
fi
echo -e "${BOLD}${BLUE}╚════════════════════════════════════════╝${NC}"
echo ""
printf "${BOLD}${BLUE}└────────────────────────────────────────┘${NC}\n"
printf "\n"
# 测试性功能警告
echo -e "${BOLD}${YELLOW}[!] 警告:此功能为测试性功能,可能会导致升级失败${NC}"
echo -e "${YELLOW} 建议运行 ./uninstall.sh 后重新执行 ./install.sh 进行全新安装${NC}"
echo ""
echo -n -e "${YELLOW}是否继续更新?(y/N) ${NC}"
# 警告提示
printf "${YELLOW}┌─ 注意事项 ─────────────────────────────┐${NC}\n"
printf "${YELLOW}${NC} • 此功能为测试性功能,可能导致升级失败 ${YELLOW}${NC}\n"
printf "${YELLOW}${NC} • 升级会覆盖所有默认引擎配置 ${YELLOW}${NC}\n"
printf "${YELLOW}${NC} • 自定义配置请先备份或创建新引擎 ${YELLOW}${NC}\n"
printf "${YELLOW}${NC} • 推荐:卸载后重新安装以获得最佳体验 ${YELLOW}${NC}\n"
printf "${YELLOW}└────────────────────────────────────────┘${NC}\n"
printf "\n"
printf "${YELLOW}是否继续更新?${NC} [y/N] "
read -r ans_continue
ans_continue=${ans_continue:-N}
if [[ ! $ans_continue =~ ^[Yy]$ ]]; then
echo -e "${CYAN}已取消更新${NC}"
printf "\n${DIM}已取消更新${NC}\n"
exit 0
fi
echo ""
printf "\n"
# Step 1: 停止服务
echo -e "${CYAN}[1/5]${NC} 停止服务..."
./stop.sh 2>&1 | sed 's/^/ /'
log_step "停止服务..."
./stop.sh 2>&1 | sed 's/^/ /'
log_ok "服务已停止"
# Step 2: 拉取代码
echo ""
echo -e "${CYAN}[2/5]${NC} 拉取代码..."
git pull --rebase 2>&1 | sed 's/^/ /'
if [ $? -ne 0 ]; then
echo -e "${RED}[错误]${NC} git pull 失败,请手动解决冲突后重试"
printf "\n"
log_step "拉取最新代码..."
if git pull --rebase 2>&1 | sed 's/^/ /'; then
log_ok "代码已更新"
else
log_error "git pull 失败,请手动解决冲突后重试"
exit 1
fi
# Step 3: 检查配置更新 + 版本同步
echo ""
echo -e "${CYAN}[3/5]${NC} 检查配置更新..."
printf "\n"
log_step "同步配置..."
merge_env_config
# 版本同步:从 VERSION 文件更新 IMAGE_TAG
@@ -130,21 +148,20 @@ if [ -f "VERSION" ]; then
if [ -n "$NEW_VERSION" ]; then
if grep -q "^IMAGE_TAG=" "docker/.env"; then
sed_inplace "s/^IMAGE_TAG=.*/IMAGE_TAG=$NEW_VERSION/" "docker/.env"
echo -e " ${GREEN}+${NC} 版本同步: IMAGE_TAG=$NEW_VERSION"
else
printf '%s\n' "IMAGE_TAG=$NEW_VERSION" >> "docker/.env"
echo -e " ${GREEN}+${NC} 新增版本: IMAGE_TAG=$NEW_VERSION"
fi
log_ok "版本同步: $NEW_VERSION"
fi
fi
# Step 4: 构建/拉取镜像
echo ""
echo -e "${CYAN}[4/5]${NC} 更新镜像..."
printf "\n"
log_step "更新镜像..."
if [ "$DEV_MODE" = true ]; then
# 开发模式:本地构建所有镜像(包括 Worker
echo -e " 构建 Worker 镜像..."
log_info "构建 Worker 镜像..."
# 读取 IMAGE_TAG
IMAGE_TAG=$(grep "^IMAGE_TAG=" "docker/.env" | cut -d'=' -f2)
@@ -153,24 +170,23 @@ if [ "$DEV_MODE" = true ]; then
fi
# 构建 Worker 镜像Worker 是临时容器,不在 compose 中,需要单独构建)
docker build -t docker-worker -f docker/worker/Dockerfile . 2>&1 | sed 's/^/ /'
docker tag docker-worker docker-worker:${IMAGE_TAG} 2>&1 | sed 's/^/ /'
echo -e " ${GREEN}OK${NC} Worker 镜像已构建: docker-worker:${IMAGE_TAG}"
docker build -t docker-worker -f docker/worker/Dockerfile . 2>&1 | sed 's/^/ /'
docker tag docker-worker docker-worker:${IMAGE_TAG} 2>&1 | sed 's/^/ /'
log_ok "Worker 镜像: docker-worker:${IMAGE_TAG}"
# 其他服务镜像由 start.sh --dev 构建
echo -e " 其他服务镜像将在启动时构建..."
log_info "其他服务镜像将在启动时构建"
else
# 生产模式:镜像由 start.sh 拉取
echo -e " 镜像将在启动时从 Docker Hub 拉取..."
log_info "镜像将在启动时从 Docker Hub 拉取"
fi
# Step 5: 启动服务
echo ""
echo -e "${CYAN}[5/5]${NC} 启动服务..."
printf "\n"
log_step "启动服务..."
./start.sh "$@"
echo ""
echo -e "${BOLD}${GREEN}════════════════════════════════════════${NC}"
echo -e "${BOLD}${GREEN} 更新完成!${NC}"
echo -e "${BOLD}${GREEN}════════════════════════════════════════${NC}"
echo ""
# 完成提示
printf "\n"
printf "${GREEN}┌────────────────────────────────────────┐${NC}\n"
printf "${GREEN}${NC} ${BOLD}${GREEN}${NC} ${BOLD}更新完成${NC} ${GREEN}${NC}\n"
printf "${GREEN}└────────────────────────────────────────┘${NC}\n"
printf "\n"