#!/bin/bash # NEX Docus 部署管理脚本 # 支持:初始化、启动、停止、重启、升级、日志查看等功能 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 项目目录 PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$PROJECT_DIR" # 检查 .env 文件 check_env() { if [ ! -f ".env" ]; then echo -e "${YELLOW}警告: .env 文件不存在${NC}" echo -e "${BLUE}正在从 .env.example 创建 .env 文件...${NC}" cp .env.example .env echo -e "${GREEN}✓ .env 文件已创建${NC}" echo -e "${YELLOW}请编辑 .env 文件,配置数据库和其他参数后再继续!${NC}" exit 1 fi } # 检查 Docker 和 Docker Compose check_docker() { if ! command -v docker &> /dev/null; then echo -e "${RED}错误: Docker 未安装${NC}" echo "请访问 https://docs.docker.com/get-docker/ 安装 Docker" exit 1 fi if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null 2>&1; then echo -e "${RED}错误: Docker Compose 未安装${NC}" echo "请访问 https://docs.docker.com/compose/install/ 安装 Docker Compose" exit 1 fi } # 获取 docker-compose 命令 get_compose_cmd() { if docker compose version &> /dev/null 2>&1; then echo "docker compose" else echo "docker-compose" fi } # 初始化部署 init() { echo -e "${BLUE}开始初始化 NEX Docus...${NC}" echo "======================================" check_env check_docker local COMPOSE_CMD=$(get_compose_cmd) # 1. 拉取镜像 echo -e "\n${BLUE}1. 拉取 Docker 镜像...${NC}" $COMPOSE_CMD pull # 2. 构建服务 echo -e "\n${BLUE}2. 构建应用镜像...${NC}" $COMPOSE_CMD build --no-cache # 3. 启动数据库和 Redis echo -e "\n${BLUE}3. 启动数据库和缓存服务...${NC}" $COMPOSE_CMD up -d mysql redis # 等待数据库就绪 echo -e "${BLUE}等待数据库就绪...${NC}" sleep 15 # 4. 初始化数据库 echo -e "\n${BLUE}4. 初始化数据库...${NC}" $COMPOSE_CMD run --rm backend python scripts/init_db.py # 5. 启动所有服务 echo -e "\n${BLUE}5. 启动所有服务...${NC}" $COMPOSE_CMD up -d # 6. 显示状态 echo -e "\n${GREEN}======================================" echo -e "✓ NEX Docus 初始化完成!" echo -e "======================================${NC}" show_info } # 启动服务 start() { echo -e "${BLUE}启动 NEX Docus 服务...${NC}" check_docker local COMPOSE_CMD=$(get_compose_cmd) $COMPOSE_CMD up -d echo -e "${GREEN}✓ 服务已启动${NC}" show_status } # 停止服务 stop() { echo -e "${YELLOW}停止 NEX Docus 服务...${NC}" check_docker local COMPOSE_CMD=$(get_compose_cmd) $COMPOSE_CMD stop echo -e "${GREEN}✓ 服务已停止${NC}" } # 重启服务 restart() { echo -e "${BLUE}重启 NEX Docus 服务...${NC}" stop sleep 2 start } # 查看服务状态 status() { check_docker local COMPOSE_CMD=$(get_compose_cmd) $COMPOSE_CMD ps } # 查看日志 logs() { check_docker local COMPOSE_CMD=$(get_compose_cmd) if [ -z "$1" ]; then echo -e "${BLUE}查看所有服务日志 (Ctrl+C 退出)${NC}" $COMPOSE_CMD logs -f else echo -e "${BLUE}查看 $1 服务日志 (Ctrl+C 退出)${NC}" $COMPOSE_CMD logs -f "$1" fi } # 升级部署 upgrade() { echo -e "${BLUE}开始升级 NEX Docus...${NC}" echo "======================================" check_docker local COMPOSE_CMD=$(get_compose_cmd) # 1. 备份数据 echo -e "\n${YELLOW}1. 建议先备份数据库...${NC}" read -p "是否继续升级?(y/n) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo -e "${YELLOW}升级已取消${NC}" exit 0 fi # 2. 拉取最新代码 echo -e "\n${BLUE}2. 拉取最新代码...${NC}" if [ -d ".git" ]; then git pull else echo -e "${YELLOW}未检测到 Git 仓库,跳过拉取代码${NC}" fi # 3. 停止服务 echo -e "\n${BLUE}3. 停止当前服务...${NC}" $COMPOSE_CMD stop backend frontend # 4. 构建新镜像 echo -e "\n${BLUE}4. 构建新镜像...${NC}" $COMPOSE_CMD build --no-cache backend frontend # 5. 运行数据库迁移 echo -e "\n${BLUE}5. 更新数据库...${NC}" $COMPOSE_CMD run --rm backend python scripts/init_db.py # 6. 启动服务 echo -e "\n${BLUE}6. 启动服务...${NC}" $COMPOSE_CMD up -d # 7. 清理旧镜像 echo -e "\n${BLUE}7. 清理旧镜像...${NC}" docker image prune -f echo -e "\n${GREEN}======================================" echo -e "✓ NEX Docus 升级完成!" echo -e "======================================${NC}" show_info } # 完全卸载 uninstall() { echo -e "${RED}警告: 此操作将删除所有容器、镜像和数据!${NC}" read -p "确认要卸载吗?(yes/no) " -r echo if [[ ! $REPLY == "yes" ]]; then echo -e "${YELLOW}卸载已取消${NC}" exit 0 fi check_docker local COMPOSE_CMD=$(get_compose_cmd) echo -e "${YELLOW}停止并删除所有容器和数据...${NC}" $COMPOSE_CMD down -v --remove-orphans echo -e "${YELLOW}删除所有镜像...${NC}" docker images | grep "nex-docus" | awk '{print $3}' | xargs -r docker rmi -f echo -e "${GREEN}✓ NEX Docus 已卸载${NC}" } # 备份数据库 backup() { check_docker local COMPOSE_CMD=$(get_compose_cmd) BACKUP_DIR="./backups" mkdir -p "$BACKUP_DIR" BACKUP_FILE="$BACKUP_DIR/nex_docus_$(date +%Y%m%d_%H%M%S).sql" echo -e "${BLUE}正在备份数据库...${NC}" # 从 .env 读取数据库配置 source .env $COMPOSE_CMD exec -T mysql mysqldump \ -u"${DB_USER}" \ -p"${DB_PASSWORD}" \ "${DB_NAME}" > "$BACKUP_FILE" if [ -f "$BACKUP_FILE" ]; then echo -e "${GREEN}✓ 数据库备份成功!${NC}" echo -e "备份文件: ${BACKUP_FILE}" else echo -e "${RED}✗ 数据库备份失败${NC}" exit 1 fi } # 恢复数据库 restore() { if [ -z "$1" ]; then echo -e "${RED}错误: 请指定备份文件${NC}" echo "用法: $0 restore " exit 1 fi if [ ! -f "$1" ]; then echo -e "${RED}错误: 备份文件不存在: $1${NC}" exit 1 fi check_docker local COMPOSE_CMD=$(get_compose_cmd) echo -e "${YELLOW}警告: 此操作将覆盖当前数据库!${NC}" read -p "确认要恢复吗?(yes/no) " -r echo if [[ ! $REPLY == "yes" ]]; then echo -e "${YELLOW}恢复已取消${NC}" exit 0 fi echo -e "${BLUE}正在恢复数据库...${NC}" # 从 .env 读取数据库配置 source .env $COMPOSE_CMD exec -T mysql mysql \ -u"${DB_USER}" \ -p"${DB_PASSWORD}" \ "${DB_NAME}" < "$1" echo -e "${GREEN}✓ 数据库恢复成功!${NC}" } # 显示访问信息 show_info() { source .env 2>/dev/null || true echo "" echo -e "${GREEN}访问信息:${NC}" echo " 前端地址: http://localhost:${FRONTEND_PORT:-8080}" echo " 后端地址: http://localhost:${BACKEND_PORT:-8000}" echo " API 文档: http://localhost:${BACKEND_PORT:-8000}/docs" echo "" echo -e "${GREEN}管理员账号:${NC}" echo " 用户名: ${ADMIN_USERNAME:-admin}" echo " 密码: ${ADMIN_PASSWORD:-Admin@123456}" echo "" echo -e "${YELLOW}提示: 请及时修改默认密码!${NC}" echo "" } # 显示状态 show_status() { echo "" echo -e "${BLUE}服务状态:${NC}" status } # 显示帮助 help() { echo "NEX Docus 部署管理脚本" echo "" echo "用法: $0 [options]" echo "" echo "命令:" echo " init 初始化并部署(首次部署使用)" echo " start 启动所有服务" echo " stop 停止所有服务" echo " restart 重启所有服务" echo " status 查看服务状态" echo " logs [服务名] 查看日志(可选指定服务:backend/frontend/mysql/redis)" echo " upgrade 升级部署" echo " backup 备份数据库" echo " restore 恢复数据库" echo " uninstall 完全卸载" echo " help 显示帮助信息" echo "" echo "示例:" echo " $0 init # 首次部署" echo " $0 start # 启动服务" echo " $0 logs backend # 查看后端日志" echo " $0 backup # 备份数据库" echo " $0 upgrade # 升级到最新版本" echo "" } # 主函数 main() { case "${1:-help}" in init) init ;; start) start ;; stop) stop ;; restart) restart ;; status) status ;; logs) logs "$2" ;; upgrade) upgrade ;; backup) backup ;; restore) restore "$2" ;; uninstall) uninstall ;; help|--help|-h) help ;; *) echo -e "${RED}错误: 未知命令 '$1'${NC}" echo "" help exit 1 ;; esac } # 执行主函数 main "$@"