| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- #!/usr/bin/env bash
- # ============================================================
- # LambdaAgentPaaS — Mac/Linux 一键启动脚本
- #
- # 用法:
- # ./deploy/start.sh # 正常启动(首次会自动初始化)
- # ./deploy/start.sh --build # 强制重新构建镜像
- # ./deploy/start.sh --reset # 清除所有数据重新初始化(谨慎!)
- #
- # 要求: Docker Desktop 已安装并运行
- # ============================================================
- set -euo pipefail
- # ── 路径常量 ─────────────────────────────────────────────────
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
- PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
- DATA_DIR="${HOME}/.agentpaas/data"
- ENV_FILE="${HOME}/.agentpaas/.env"
- APP_PORT="${AGENTPAAS_PORT:-8000}"
- APP_URL="http://localhost:${APP_PORT}"
- # ── 颜色输出 ─────────────────────────────────────────────────
- RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
- BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
- info() { echo -e "${BLUE}ℹ ${NC}$*"; }
- success() { echo -e "${GREEN}✅ $*${NC}"; }
- warn() { echo -e "${YELLOW}⚠️ $*${NC}"; }
- error() { echo -e "${RED}❌ $*${NC}" >&2; }
- header() { echo -e "\n${BOLD}${CYAN}$*${NC}\n"; }
- # ── 参数解析 ─────────────────────────────────────────────────
- BUILD_FLAG=""
- RESET_FLAG=""
- for arg in "$@"; do
- case $arg in
- --build) BUILD_FLAG="--build" ;;
- --reset) RESET_FLAG="yes" ;;
- esac
- done
- # ── 检查 Docker ──────────────────────────────────────────────
- check_docker() {
- if ! command -v docker &>/dev/null; then
- error "未找到 Docker。请先安装 Docker Desktop:"
- echo " https://docs.docker.com/desktop/install/mac-install/"
- echo ""
- if [[ "$OSTYPE" == "darwin"* ]]; then
- read -p "是否现在打开下载页面? (y/N) " yn
- [[ "$yn" =~ ^[Yy]$ ]] && open "https://docs.docker.com/desktop/install/mac-install/"
- fi
- exit 1
- fi
- if ! docker info &>/dev/null 2>&1; then
- info "Docker Desktop 未运行,正在启动..."
- if [[ "$OSTYPE" == "darwin"* ]]; then
- open -a "Docker Desktop" 2>/dev/null || open -a "Docker" 2>/dev/null || true
- fi
- echo -n "等待 Docker 就绪"
- local wait=0
- until docker info &>/dev/null 2>&1; do
- echo -n "."
- sleep 2
- ((wait+=2))
- if (( wait > 60 )); then
- echo ""
- error "Docker 启动超时(60s)。请手动启动 Docker Desktop 后重试。"
- exit 1
- fi
- done
- echo ""
- success "Docker 已就绪"
- fi
- }
- # ── 检查 docker compose ──────────────────────────────────────
- check_compose() {
- if docker compose version &>/dev/null 2>&1; then
- COMPOSE_CMD="docker compose"
- elif command -v docker-compose &>/dev/null; then
- COMPOSE_CMD="docker-compose"
- else
- error "未找到 docker compose。请升级 Docker Desktop 到最新版本。"
- exit 1
- fi
- }
- # ── 初始化数据目录 ────────────────────────────────────────────
- init_data_dir() {
- mkdir -p "${DATA_DIR}/instances"
- mkdir -p "${DATA_DIR}/knowledge_bases"
- mkdir -p "${DATA_DIR}/logs"
- # 限制 data 目录权限(避免被其他用户读取)
- chmod 700 "${HOME}/.agentpaas" 2>/dev/null || true
- }
- # ── 初始化 .env 配置文件 ─────────────────────────────────────
- init_env() {
- if [[ -f "$ENV_FILE" && -z "$RESET_FLAG" ]]; then
- return 0 # 已存在且不是 reset 模式
- fi
- header "🔧 首次配置初始化"
- mkdir -p "$(dirname "$ENV_FILE")"
- # 复制模板
- cp "${PROJECT_DIR}/.env.template" "$ENV_FILE"
- # 自动生成 MASTER_KEY(安全随机 64 字节 hex)
- if command -v python3 &>/dev/null; then
- MASTER_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))")
- else
- MASTER_KEY=$(openssl rand -hex 32)
- fi
- # 写入 DATA_DIR 和 MASTER_KEY
- sed -i.bak "s|^AGENTPAAS_DATA_DIR=.*|AGENTPAAS_DATA_DIR=${DATA_DIR}|" "$ENV_FILE"
- sed -i.bak "s|^AGENTPAAS_MASTER_KEY=.*|AGENTPAAS_MASTER_KEY=${MASTER_KEY}|" "$ENV_FILE"
- rm -f "${ENV_FILE}.bak"
- success "配置文件已创建: $ENV_FILE"
- echo ""
- warn "请编辑 ${ENV_FILE} 填写至少一个 LLM API Key:"
- echo " DASHSCOPE_API_KEY= (阿里云百炼,国内推荐)"
- echo " ANTHROPIC_API_KEY= (Claude)"
- echo " OPENAI_API_KEY= (GPT)"
- echo ""
- echo "编辑完成后重新运行此脚本。"
- echo ""
- read -p "是否现在打开配置文件编辑? (Y/n) " yn
- yn="${yn:-Y}"
- if [[ "$yn" =~ ^[Yy]$ ]]; then
- # 尝试用系统默认编辑器打开
- ${EDITOR:-$(command -v nano || command -v vi || echo "open")} "$ENV_FILE"
- fi
- }
- # ── 检查是否配置了至少一个 API Key ───────────────────────────
- check_api_keys() {
- local has_key=false
- local key_vars=(DASHSCOPE_API_KEY OPENAI_API_KEY ANTHROPIC_API_KEY
- DEEPSEEK_API_KEY ZHIPU_API_KEY MOONSHOT_API_KEY)
- for var in "${key_vars[@]}"; do
- val=$(grep "^${var}=" "$ENV_FILE" 2>/dev/null | cut -d= -f2 | tr -d ' \r\n')
- if [[ -n "$val" ]]; then
- has_key=true
- break
- fi
- done
- if [[ "$has_key" == "false" ]]; then
- warn "未检测到任何 LLM API Key。"
- warn "Agent 功能将不可用,直到在 ${ENV_FILE} 中配置至少一个 API Key。"
- echo ""
- read -p "继续启动? (y/N) " yn
- [[ "$yn" =~ ^[Yy]$ ]] || exit 0
- fi
- }
- # ── 启动服务 ─────────────────────────────────────────────────
- start_services() {
- header "🚀 启动 LambdaAgentPaaS"
- cd "$PROJECT_DIR"
- # 将 DATA_DIR 导出供 docker-compose.yml 使用
- export AGENTPAAS_DATA_DIR="$DATA_DIR"
- # 加载 .env 中的其他变量
- set -a
- source "$ENV_FILE"
- set +a
- if [[ -n "$RESET_FLAG" ]]; then
- info "清除旧容器和镜像..."
- $COMPOSE_CMD down --remove-orphans 2>/dev/null || true
- docker rmi lambdagentpaas:latest 2>/dev/null || true
- fi
- info "构建并启动容器(首次构建约 3-5 分钟)..."
- $COMPOSE_CMD up -d ${BUILD_FLAG}
- }
- # ── 等待健康检查 ─────────────────────────────────────────────
- wait_for_health() {
- echo -n "等待服务就绪"
- local wait=0
- until curl -sf "${APP_URL}/health" &>/dev/null; do
- echo -n "."
- sleep 2
- ((wait+=2))
- if (( wait > 120 )); then
- echo ""
- error "服务启动超时(120s)"
- echo ""
- echo "查看日志:"
- echo " docker logs lambdagentpaas"
- exit 1
- fi
- done
- echo ""
- }
- # ── 打印成功信息 ─────────────────────────────────────────────
- print_success() {
- echo ""
- echo -e "${GREEN}╔══════════════════════════════════════════════╗${NC}"
- echo -e "${GREEN}║ 🎉 LambdaAgentPaaS 已成功启动! ║${NC}"
- echo -e "${GREEN}╠══════════════════════════════════════════════╣${NC}"
- echo -e "${GREEN}║ Web 界面: ${BOLD}${APP_URL}${NC}${GREEN} ║${NC}"
- echo -e "${GREEN}║ API 文档: ${APP_URL}/docs ║${NC}"
- echo -e "${GREEN}╠══════════════════════════════════════════════╣${NC}"
- echo -e "${GREEN}║ 数据目录: ${DATA_DIR}${NC}"
- echo -e "${GREEN}║ 配置文件: ${ENV_FILE}${NC}"
- echo -e "${GREEN}╠══════════════════════════════════════════════╣${NC}"
- echo -e "${GREEN}║ 停止服务: ./deploy/stop.sh ║${NC}"
- echo -e "${GREEN}║ 查看日志: docker logs -f lambdagentpaas ║${NC}"
- echo -e "${GREEN}╚══════════════════════════════════════════════╝${NC}"
- echo ""
- }
- # ── 主流程 ───────────────────────────────────────────────────
- main() {
- header "LambdaAgentPaaS 启动器"
- check_docker
- check_compose
- init_data_dir
- init_env
- check_api_keys
- start_services
- wait_for_health
- print_success
- # 自动打开浏览器
- if [[ "$OSTYPE" == "darwin"* ]]; then
- open "$APP_URL"
- elif command -v xdg-open &>/dev/null; then
- xdg-open "$APP_URL"
- fi
- }
- main "$@"
|