Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force

- ⚠️ 请妥善保存脚本输出的**管理员令牌**(Admin Token),这是登录后台的唯一凭证!
- ⚠️ Windows 用户:如果未安装 Docker Desktop,脚本会自动打开下载页面
- ⚠️ 软件更新:请参考 `Docker Compose 启动章节`,deploy脚本仅用于首次部署,并不用于更新软件 (环境限制,目前仅暂在 Linux 安装脚本确保了部署幂等性,未覆盖 Powershell 脚本)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

当前的说明文字有些冗长,并且将操作指引和实现细节的备注混合在了一起,可能会让用户困惑。

建议将更新操作的指引和脚本幂等性的状态说明分开,使信息更清晰。同时,更新说明中引用的章节可以更精确地指向包含升级指南的 部署指南 章节,而不是 Docker Compose 启动章节

Suggested change
- ⚠️ 软件更新:请参考 `Docker Compose 启动章节`,deploy脚本仅用于首次部署,并不用于更新软件 (环境限制,目前仅暂在 Linux 安装脚本确保了部署幂等性,未覆盖 Powershell 脚本)
- ⚠️ 软件更新:`deploy` 脚本主要用于首次部署。如需更新,请参考 `部署指南` 章节中的升级说明。 (注意:目前仅 Linux 脚本支持幂等性检查,Windows 的 PowerShell 脚本暂不支持。)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

文案存在小笔误。

"目前仅在 Linux" 中的"暂"字应删除或改为"目前仅在"。

📝 建议的修改
-- ⚠️ 软件更新:请参考 `Docker Compose 启动章节`,deploy脚本仅用于首次部署,并不用于更新软件 (环境限制,目前仅暂在 Linux 安装脚本确保了部署幂等性,未覆盖 Powershell 脚本)
+- ⚠️ 软件更新:请参考 `Docker Compose 启动章节`,deploy 脚本仅用于首次部署,并不用于更新软件(环境限制,目前仅在 Linux 安装脚本确保了部署幂等性,未覆盖 PowerShell 脚本)

另外建议:

  • "Powershell" → "PowerShell"(官方拼写)
  • 括号使用中文全角括号 () 以保持一致性
  • deploy脚本 建议改为 deploy 脚本,增加空格提升可读性
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- ⚠️ 软件更新:请参考 `Docker Compose 启动章节`deploy脚本仅用于首次部署,并不用于更新软件 (环境限制,目前仅暂在 Linux 安装脚本确保了部署幂等性,未覆盖 Powershell 脚本)
- ⚠️ 软件更新:请参考 `Docker Compose 启动章节`deploy 脚本仅用于首次部署,并不用于更新软件环境限制,目前仅在 Linux 安装脚本确保了部署幂等性,未覆盖 PowerShell 脚本
🤖 Prompt for AI Agents
In @README.md at line 152, Fix the wording in the README sentence that currently
reads "目前仅暂在 Linux 安装脚本确保了部署幂等性,未覆盖 Powershell 脚本": remove the extra character
"暂" so it reads "目前仅在 Linux 安装脚本确保了部署幂等性,未覆盖 PowerShell 脚本"; also change
"Powershell" to "PowerShell", replace "deploy脚本" with "deploy 脚本" (add a space),
and convert any parentheses around that clause to full-width Chinese parentheses
"()" for consistency.


### 三步启动(Docker Compose)

Expand Down
97 changes: 95 additions & 2 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ DIR_ARG=""
DOMAIN_ARG=""
ENABLE_CADDY=false
NON_INTERACTIVE=false
FORCE_REINSTALL=false

show_help() {
cat << EOF
Expand All @@ -62,6 +63,7 @@ Options:
--domain <domain> Domain for Caddy HTTPS (enables Caddy automatically)
--enable-caddy Enable Caddy reverse proxy without HTTPS (HTTP only)
-y, --yes Non-interactive mode (skip prompts, use defaults)
-f, --force Force reinstall (remove existing installation)
-h, --help Show this help message

Examples:
Expand Down Expand Up @@ -128,6 +130,10 @@ parse_args() {
NON_INTERACTIVE=true
shift
;;
-f|--force)
FORCE_REINSTALL=true
shift
;;
-h|--help)
show_help
exit 0
Expand Down Expand Up @@ -218,6 +224,90 @@ detect_os() {
log_info "Detected OS: $OS_TYPE"
}

check_existing_installation() {
log_info "Checking for existing installation..."

local installation_found=false
local existing_containers=()

# Check if deployment directory exists with key files
if [[ -d "$DEPLOY_DIR" ]]; then
if [[ -f "$DEPLOY_DIR/docker-compose.yaml" ]] || [[ -f "$DEPLOY_DIR/.env" ]]; then
installation_found=true
log_warning "Found existing installation at: $DEPLOY_DIR"
fi
fi

# Check for running containers with our naming pattern
if command -v docker &> /dev/null; then
while IFS= read -r container; do
existing_containers+=("$container")
done < <(docker ps -a --filter "name=claude-code-hub-" --format "{{.Names}}" 2>/dev/null)

if [[ ${#existing_containers[@]} -gt 0 ]]; then
installation_found=true
log_warning "Found existing Docker containers:"
for container in "${existing_containers[@]}"; do
echo " - $container"
done
fi
fi

# If installation found and not forcing reinstall, abort
if [[ "$installation_found" == true ]] && [[ "$FORCE_REINSTALL" != true ]]; then
echo ""
log_error "Claude Code Hub is already installed on this system!"
echo ""
echo -e "${YELLOW}To manage your existing installation:${NC}"
echo -e " View logs: ${BLUE}cd $DEPLOY_DIR && docker compose logs -f${NC}"
echo -e " Stop: ${BLUE}cd $DEPLOY_DIR && docker compose down${NC}"
echo -e " Restart: ${BLUE}cd $DEPLOY_DIR && docker compose restart${NC}"
echo ""
echo -e "${YELLOW}To completely remove and reinstall:${NC}"
echo -e " 1. Stop services: ${BLUE}cd $DEPLOY_DIR && docker compose down -v${NC}"
echo -e " 2. Remove directory: ${BLUE}rm -rf $DEPLOY_DIR${NC}"
echo -e " 3. Re-run this script"
echo ""
echo -e "${YELLOW}Or use the --force flag to automatically remove and reinstall:${NC}"
echo -e " ${BLUE}$0 --force${NC}"
echo ""
exit 1
fi

# If forcing reinstall, clean up existing installation
if [[ "$installation_found" == true ]] && [[ "$FORCE_REINSTALL" == true ]]; then
log_warning "Force reinstall enabled. Removing existing installation..."

# Stop and remove containers
if [[ ${#existing_containers[@]} -gt 0 ]]; then
log_info "Stopping and removing existing containers..."
if [[ -d "$DEPLOY_DIR" ]] && [[ -f "$DEPLOY_DIR/docker-compose.yaml" ]]; then
cd "$DEPLOY_DIR"
if docker compose version &> /dev/null; then
docker compose down -v 2>/dev/null || true
else
docker-compose down -v 2>/dev/null || true
fi
Comment on lines +285 to +290

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

cd "$DEPLOY_DIR" 会改变当前脚本的全局工作目录,这可能会对后续命令产生意料之外的影响。虽然目前脚本的其他部分似乎能够适应这个变化,但这是一种有风险的实践,降低了代码的可维护性。

建议使用子 shell (subshell) () 来隔离目录切换操作。这样可以确保 docker compose down 命令在正确的目录执行,同时不会影响脚本其余部分的执行环境,从而提高脚本的健壮性。

Suggested change
cd "$DEPLOY_DIR"
if docker compose version &> /dev/null; then
docker compose down -v 2>/dev/null || true
else
docker-compose down -v 2>/dev/null || true
fi
(
cd "$DEPLOY_DIR"
if docker compose version &> /dev/null; then
docker compose down -v 2>/dev/null || true
else
docker-compose down -v 2>/dev/null || true
fi
)

fi

# Force remove any remaining containers
for container in "${existing_containers[@]}"; do
docker rm -f "$container" 2>/dev/null || true
done
fi
Comment on lines +277 to +297
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

数据丢失风险:--force 选项会删除数据库数据,建议添加确认提示。

docker compose down -v 会删除所有卷(包括 PostgreSQL 数据)。在非交互模式下使用 --force 可能导致用户意外丢失生产数据。

建议:在非交互模式下添加额外确认,或至少在帮助信息中明确警告数据会被删除。

🔧 建议的改进方案
     # If forcing reinstall, clean up existing installation
     if [[ "$installation_found" == true ]] && [[ "$FORCE_REINSTALL" == true ]]; then
+        if [[ "$NON_INTERACTIVE" != true ]]; then
+            echo ""
+            log_warning "This will DELETE all existing data including the database!"
+            read -p "Are you sure you want to continue? [y/N]: " confirm
+            if [[ "$confirm" != "y" ]] && [[ "$confirm" != "Y" ]]; then
+                log_info "Aborted by user."
+                exit 0
+            fi
+        else
+            log_warning "Force reinstall in non-interactive mode - all existing data will be deleted!"
+        fi
         log_warning "Force reinstall enabled. Removing existing installation..."
🤖 Prompt for AI Agents
In @scripts/deploy.sh around lines 277 - 297, When FORCE_REINSTALL is true the
script runs "docker compose down -v" which will delete volumes and can drop DB
data; before stopping/removing containers (the block that checks
existing_containers and DEPLOY_DIR and runs "docker compose down -v" /
"docker-compose down -v") add an explicit confirmation step: if the script is
running interactively (tty) prompt the user to confirm destructive removal of
volumes, and if non-interactive require an explicit opt-in environment variable
or flag (e.g., FORCE_REINSTALL_CONFIRM=yes or --confirm-delete-volumes)
otherwise abort with a clear log_warning that volumes (e.g., Postgres data) will
be deleted; ensure the check references FORCE_REINSTALL, existing_containers,
DEPLOY_DIR and the exact docker compose commands so the destructive down -v only
runs after confirmation.


# Remove deployment directory
if [[ -d "$DEPLOY_DIR" ]]; then
log_info "Removing deployment directory: $DEPLOY_DIR"
rm -rf "$DEPLOY_DIR"
fi
Comment on lines +278 to +303
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --force reinstall removes the existing deployment directory without preserving credentials. This causes data loss of the admin token and database password from the original .env file. When users run --force, they'll lose access to their existing database and admin panel.

Issue: Lines 300-302 delete $DEPLOY_DIR which contains the .env file with original credentials, but lines 860-862 generate new random credentials. The new credentials won't match the existing database data in Docker volumes (if those volumes survive).

Fix: Before removing the directory, backup existing credentials from the .env file and restore them after cleanup. Extract the admin token and database password values, then modify generate_admin_token() and generate_db_password() functions to skip generation if values are already set from backup.


log_success "Existing installation removed successfully"
else
log_success "No existing installation found. Proceeding with fresh installation..."
fi
}

select_branch() {
# Skip if branch already set via CLI or non-interactive mode
if [[ -n "$BRANCH_ARG" ]]; then
Expand Down Expand Up @@ -748,10 +838,13 @@ main() {
print_header

detect_os

# Apply CLI overrides after OS detection (for deploy dir)
validate_inputs


# Check for existing installation before proceeding
check_existing_installation

if ! check_docker; then
log_warning "Docker is not installed. Attempting to install..."
install_docker
Expand Down
Loading