Files
crawl4ai/deploy/installer/deploy.sh
unclecode cd02616218 feat(cnode): add standalone CLI for Docker server management
- Reorganized server management code:
  - Moved server_cli.py -> deploy/docker/cnode_cli.py
  - Moved server_manager.py -> deploy/docker/server_manager.py

- Created fast Python-based installation (0.1s startup):
  - deploy/installer/cnode_pkg/ - Standalone package
  - deploy/installer/install-cnode.sh - Local installer
  - deploy/installer/deploy.sh - Remote installer for users

- Added backward compatibility:
  - crawl4ai/cli.py: 'crwl server' redirects to 'cnode'
  - Updated tests to match new CLI structure (12/12 passing)

- Automated sync workflow:
  - .githooks/pre-commit - Auto-syncs source to package
  - setup-hooks.sh - One-time setup for contributors
  - deploy/installer/sync-cnode.sh - Manual sync script

Performance:
  - Startup time: 0.1s (49x faster than PyInstaller)
  - Size: ~50KB wrapper vs 8.8MB binary

Commands:
  cnode start [--replicas N]  # Start server/cluster
  cnode status                # Check status
  cnode scale N               # Scale replicas
  cnode logs [-f]             # View logs
  cnode stop                  # Stop server
2025-10-21 09:31:18 +08:00

218 lines
6.9 KiB
Bash
Executable File

#!/bin/bash
# Crawl4AI Node Manager (cnode) Installation Script
# Usage: curl -sSL https://crawl4ai.com/deploy.sh | bash
# Or: wget -qO- https://crawl4ai.com/deploy.sh | bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
INSTALL_DIR="${INSTALL_DIR:-/usr/local/bin}"
BINARY_NAME="cnode"
GITHUB_REPO="unclecode/crawl4ai"
RELEASE_TAG="${CNODE_VERSION:-latest}"
echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Crawl4AI Node Manager (cnode) Installation Script ║${NC}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}\n"
# Detect OS and architecture
detect_platform() {
OS="$(uname -s)"
ARCH="$(uname -m)"
case "$OS" in
Linux*)
OS_TYPE="linux"
;;
Darwin*)
OS_TYPE="macos"
;;
*)
echo -e "${RED}Error: Unsupported operating system: $OS${NC}"
exit 1
;;
esac
case "$ARCH" in
x86_64|amd64)
ARCH_TYPE="amd64"
;;
aarch64|arm64)
ARCH_TYPE="arm64"
;;
*)
echo -e "${RED}Error: Unsupported architecture: $ARCH${NC}"
exit 1
;;
esac
echo -e "${BLUE}Detected platform: ${YELLOW}$OS_TYPE-$ARCH_TYPE${NC}"
}
# Check if Docker is installed
check_docker() {
if ! command -v docker &> /dev/null; then
echo -e "${YELLOW}⚠️ Docker not found. cnode requires Docker to manage server instances.${NC}"
echo -e "${YELLOW}Install Docker from: https://docs.docker.com/get-docker/${NC}\n"
read -p "Continue installation anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
else
echo -e "${GREEN}✓ Docker is installed${NC}"
fi
}
# Check write permissions
check_permissions() {
if [ ! -w "$INSTALL_DIR" ]; then
echo -e "${YELLOW}⚠️ No write permission for $INSTALL_DIR${NC}"
echo -e "${YELLOW}The script will attempt to use sudo for installation.${NC}\n"
USE_SUDO="sudo"
else
USE_SUDO=""
fi
}
# Download binary
download_binary() {
BINARY_URL="https://github.com/$GITHUB_REPO/releases/download/$RELEASE_TAG/cnode-$OS_TYPE-$ARCH_TYPE"
echo -e "${BLUE}Downloading cnode from GitHub...${NC}"
echo -e "${YELLOW}URL: $BINARY_URL${NC}\n"
# Create temp directory
TMP_DIR="$(mktemp -d)"
TMP_FILE="$TMP_DIR/$BINARY_NAME"
# Download with curl or wget
if command -v curl &> /dev/null; then
if ! curl -fSL "$BINARY_URL" -o "$TMP_FILE"; then
echo -e "${RED}Error: Failed to download binary${NC}"
echo -e "${YELLOW}URL: $BINARY_URL${NC}"
rm -rf "$TMP_DIR"
exit 1
fi
elif command -v wget &> /dev/null; then
if ! wget -q "$BINARY_URL" -O "$TMP_FILE"; then
echo -e "${RED}Error: Failed to download binary${NC}"
echo -e "${YELLOW}URL: $BINARY_URL${NC}"
rm -rf "$TMP_DIR"
exit 1
fi
else
echo -e "${RED}Error: Neither curl nor wget found${NC}"
echo -e "${YELLOW}Please install curl or wget and try again${NC}"
rm -rf "$TMP_DIR"
exit 1
fi
# Make executable
chmod +x "$TMP_FILE"
echo "$TMP_FILE"
}
# Install binary
install_binary() {
local tmp_file="$1"
local install_path="$INSTALL_DIR/$BINARY_NAME"
echo -e "\n${BLUE}Installing cnode to $install_path...${NC}"
# Check if already installed
if [ -f "$install_path" ]; then
echo -e "${YELLOW}⚠️ cnode is already installed${NC}"
read -p "Overwrite existing installation? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}Installation cancelled${NC}"
rm -rf "$(dirname "$tmp_file")"
exit 0
fi
fi
# Install
if ! $USE_SUDO mv "$tmp_file" "$install_path"; then
echo -e "${RED}Error: Failed to install binary${NC}"
rm -rf "$(dirname "$tmp_file")"
exit 1
fi
# Cleanup temp directory
rm -rf "$(dirname "$tmp_file")"
echo -e "${GREEN}✓ Installation successful${NC}"
}
# Verify installation
verify_installation() {
echo -e "\n${BLUE}Verifying installation...${NC}"
if ! command -v $BINARY_NAME &> /dev/null; then
echo -e "${RED}Error: $BINARY_NAME not found in PATH${NC}"
echo -e "${YELLOW}You may need to add $INSTALL_DIR to your PATH${NC}"
echo -e "${YELLOW}Add this to your ~/.bashrc or ~/.zshrc:${NC}"
echo -e "${YELLOW}export PATH=\"$INSTALL_DIR:\$PATH\"${NC}\n"
exit 1
fi
# Test version
if $BINARY_NAME --help &> /dev/null; then
echo -e "${GREEN}$BINARY_NAME is working correctly${NC}"
else
echo -e "${RED}Error: $BINARY_NAME failed to execute${NC}"
exit 1
fi
}
# Show completion message
show_completion() {
local version
version=$($BINARY_NAME --help | head -1 || echo "unknown")
echo -e "\n${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Installation Complete! ║${NC}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}\n"
echo -e "${BLUE}cnode is now installed and ready to use!${NC}\n"
echo -e "${YELLOW}Quick Start:${NC}"
echo -e " ${GREEN}cnode start${NC} # Start single server instance"
echo -e " ${GREEN}cnode start --replicas 5${NC} # Start 5-replica cluster"
echo -e " ${GREEN}cnode status${NC} # Check server status"
echo -e " ${GREEN}cnode logs -f${NC} # Follow server logs"
echo -e " ${GREEN}cnode scale 10${NC} # Scale to 10 replicas"
echo -e " ${GREEN}cnode stop${NC} # Stop server"
echo -e "\n${YELLOW}For more information:${NC}"
echo -e " ${BLUE}cnode --help${NC}"
echo -e " ${BLUE}https://github.com/$GITHUB_REPO${NC}\n"
}
# Main installation flow
main() {
detect_platform
check_docker
check_permissions
# Download and install
TMP_FILE=$(download_binary)
install_binary "$TMP_FILE"
# Verify
verify_installation
show_completion
}
# Run installation
main