Spaces:
Sleeping
Sleeping
charSLee013
feat: complete Hugging Face Spaces deployment with production-ready CognitiveKernel-Launchpad
1ea26af
| # ============================================================================ | |
| # CognitiveKernel-Pro Web Server Docker Build and Verification Script | |
| # ============================================================================ | |
| # Features: Auto-install Docker, build image, start container, verify service | |
| # Location: Should be placed in ck_pro/ck_web/_web/ directory with Dockerfile | |
| # ============================================================================ | |
| set -euo pipefail | |
| # Configuration | |
| readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| readonly IMAGE_NAME="ck-web-server" | |
| readonly IMAGE_TAG="$(date +%Y%m%d)" | |
| readonly CONTAINER_NAME="ck-web-server" | |
| readonly HOST_PORT="9000" | |
| readonly CONTAINER_PORT="9000" | |
| readonly DOCKER_INSTALL_URL="https://get.docker.com" | |
| # Detect if sudo is needed for Docker | |
| DOCKER_CMD="docker" | |
| if [ "$EUID" -ne 0 ] && command -v sudo >/dev/null 2>&1; then | |
| DOCKER_CMD="sudo docker" | |
| fi | |
| # Color logging | |
| readonly RED='\033[0;31m' | |
| readonly GREEN='\033[0;32m' | |
| readonly YELLOW='\033[1;33m' | |
| readonly BLUE='\033[0;34m' | |
| readonly NC='\033[0m' | |
| log_info() { | |
| echo -e "${BLUE}[INFO]${NC} $1" | |
| } | |
| log_error() { | |
| echo -e "${RED}[ERROR]${NC} $1" | |
| } | |
| log_success() { | |
| echo -e "${GREEN}[SUCCESS]${NC} $1" | |
| } | |
| log_warn() { | |
| echo -e "${YELLOW}[WARN]${NC} $1" | |
| } | |
| log_step() { | |
| echo -e "${BLUE}[STEP]${NC} $1" | |
| } | |
| # Detect operating system | |
| detect_os() { | |
| if [[ "$OSTYPE" == "linux-gnu"* ]]; then | |
| echo "linux" | |
| elif [[ "$OSTYPE" == "darwin"* ]]; then | |
| echo "macos" | |
| elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]]; then | |
| echo "windows" | |
| else | |
| echo "unknown" | |
| fi | |
| } | |
| # Install Docker | |
| install_docker() { | |
| local os_type=$(detect_os) | |
| log_step "Detected operating system: $os_type" | |
| case "$os_type" in | |
| "linux") | |
| log_info "Auto-installing Docker on Linux system..." | |
| # Download and execute Docker official installation script | |
| log_info "Downloading Docker official installation script..." | |
| if command -v curl >/dev/null 2>&1; then | |
| curl -fsSL "$DOCKER_INSTALL_URL" -o install-docker.sh | |
| elif command -v wget >/dev/null 2>&1; then | |
| wget -qO install-docker.sh "$DOCKER_INSTALL_URL" | |
| else | |
| log_error "Need curl or wget to download Docker installation script" | |
| log_info "Please install Docker manually: https://docs.docker.com/engine/install/" | |
| exit 1 | |
| fi | |
| # Verify script content (optional) | |
| log_info "Verifying installation script..." | |
| if ! grep -q "docker install script" install-docker.sh; then | |
| log_error "Downloaded script is not a valid Docker installation script" | |
| rm -f install-docker.sh | |
| exit 1 | |
| fi | |
| # Execute installation | |
| log_info "Executing Docker installation (requires sudo privileges)..." | |
| chmod +x install-docker.sh | |
| sudo sh install-docker.sh | |
| # Clean up installation script | |
| rm -f install-docker.sh | |
| # Start Docker service | |
| log_info "Starting Docker service..." | |
| sudo systemctl start docker || sudo service docker start || true | |
| sudo systemctl enable docker || true | |
| # Add current user to docker group (optional) | |
| if [ "$EUID" -ne 0 ]; then | |
| log_info "Adding current user to docker group..." | |
| sudo usermod -aG docker "$USER" || true | |
| log_warn "Please logout and login again for docker group permissions to take effect, or use sudo docker commands" | |
| fi | |
| ;; | |
| "macos") | |
| log_error "Please install Docker Desktop manually on macOS" | |
| log_info "Download: https://docs.docker.com/desktop/install/mac-install/" | |
| exit 1 | |
| ;; | |
| "windows") | |
| log_error "Please install Docker Desktop manually on Windows" | |
| log_info "Download: https://docs.docker.com/desktop/install/windows-install/" | |
| exit 1 | |
| ;; | |
| *) | |
| log_error "Unsupported operating system, please install Docker manually" | |
| log_info "Installation guide: https://docs.docker.com/engine/install/" | |
| exit 1 | |
| ;; | |
| esac | |
| } | |
| # Check dependencies | |
| check_dependencies() { | |
| log_step "Checking system dependencies..." | |
| # Check Docker | |
| if ! command -v docker >/dev/null 2>&1; then | |
| log_warn "Docker not installed, starting auto-installation..." | |
| install_docker | |
| # Re-check Docker | |
| if ! command -v docker >/dev/null 2>&1; then | |
| log_error "Docker installation failed, please install manually" | |
| exit 1 | |
| fi | |
| else | |
| log_success "Docker is installed" | |
| fi | |
| # Check if Docker is running | |
| log_info "Checking Docker service status..." | |
| if ! $DOCKER_CMD info >/dev/null 2>&1; then | |
| log_warn "Docker service not running, attempting to start..." | |
| # Try to start Docker service | |
| if command -v systemctl >/dev/null 2>&1; then | |
| sudo systemctl start docker || true | |
| elif command -v service >/dev/null 2>&1; then | |
| sudo service docker start || true | |
| fi | |
| # Wait for service to start | |
| sleep 3 | |
| # Check again | |
| if ! $DOCKER_CMD info >/dev/null 2>&1; then | |
| log_error "Failed to start Docker service" | |
| log_info "Please start Docker service manually:" | |
| log_info " Linux: sudo systemctl start docker" | |
| log_info " macOS: Start Docker Desktop application" | |
| exit 1 | |
| fi | |
| fi | |
| log_success "Docker service is running normally" | |
| # Check required files | |
| local required_files=("Dockerfile" "package.json" "server.js" "entrypoint.sh") | |
| for file in "${required_files[@]}"; do | |
| if [[ ! -f "$file" ]]; then | |
| log_error "Missing file: $file" | |
| log_info "Please ensure running this script in the correct directory (ck_pro/ck_web/_web/)" | |
| exit 1 | |
| fi | |
| done | |
| log_success "All dependency checks passed" | |
| } | |
| # Stop and remove old container (if exists) | |
| cleanup_old_container() { | |
| if $DOCKER_CMD ps -a --format '{{.Names}}' | grep -q "^$CONTAINER_NAME$"; then | |
| log_info "Stopping and removing old container: $CONTAINER_NAME" | |
| $DOCKER_CMD stop "$CONTAINER_NAME" >/dev/null 2>&1 || true | |
| $DOCKER_CMD rm "$CONTAINER_NAME" >/dev/null 2>&1 || true | |
| fi | |
| } | |
| # Build Docker image | |
| build_image() { | |
| log_step "Building Docker image: $IMAGE_NAME:$IMAGE_TAG" | |
| # Build with verbose output to see detailed errors | |
| if $DOCKER_CMD build --progress=plain -t "$IMAGE_NAME:$IMAGE_TAG" .; then | |
| log_success "Docker image built successfully" | |
| # Show image information | |
| $DOCKER_CMD images "$IMAGE_NAME:$IMAGE_TAG" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedAt}}" | |
| else | |
| log_error "Docker image build failed" | |
| log_info "Try running with more verbose output:" | |
| log_info "$DOCKER_CMD build --progress=plain --no-cache -t $IMAGE_NAME:$IMAGE_TAG ." | |
| exit 1 | |
| fi | |
| } | |
| # Start background container | |
| start_container() { | |
| log_step "Starting background container: $CONTAINER_NAME" | |
| # Clean up old container | |
| cleanup_old_container | |
| # Start new container | |
| log_info "Container startup configuration:" | |
| log_info " Image: $IMAGE_NAME:$IMAGE_TAG" | |
| log_info " Port: $HOST_PORT:$CONTAINER_PORT" | |
| log_info " Memory limit: 1GB" | |
| log_info " CPU limit: 1.0" | |
| $DOCKER_CMD run -d \ | |
| --name "$CONTAINER_NAME" \ | |
| -p "$HOST_PORT:$CONTAINER_PORT" \ | |
| --restart unless-stopped \ | |
| --memory=1g \ | |
| --cpus=1.0 \ | |
| "$IMAGE_NAME:$IMAGE_TAG" | |
| if [ $? -eq 0 ]; then | |
| log_success "Container started successfully" | |
| log_info "Container name: $CONTAINER_NAME" | |
| log_info "Access URL: http://localhost:$HOST_PORT" | |
| else | |
| log_error "Container startup failed" | |
| log_info "View error logs:" | |
| $DOCKER_CMD logs "$CONTAINER_NAME" 2>/dev/null || true | |
| exit 1 | |
| fi | |
| } | |
| # Wait for service to start | |
| wait_for_service() { | |
| log_info "Waiting for service to start..." | |
| local max_attempts=30 | |
| local attempt=1 | |
| while [ $attempt -le $max_attempts ]; do | |
| if curl -s "http://localhost:$HOST_PORT/health" >/dev/null 2>&1; then | |
| log_success "Service started (attempt $attempt/$max_attempts)" | |
| return 0 | |
| fi | |
| echo -n "." | |
| sleep 2 | |
| ((attempt++)) | |
| done | |
| echo "" | |
| log_error "Service startup timeout" | |
| return 1 | |
| } | |
| # HTTP verification tests | |
| verify_container() { | |
| log_info "Starting HTTP verification tests..." | |
| # Test 1: Health check | |
| log_info "Test 1: Health check endpoint" | |
| if curl -s "http://localhost:$HOST_PORT/health" | grep -q "healthy"; then | |
| log_success "β Health check passed" | |
| else | |
| log_error "β Health check failed" | |
| return 1 | |
| fi | |
| # Test 2: Browser allocation | |
| log_info "Test 2: Browser allocation test" | |
| local browser_response | |
| browser_response=$(curl -s -X POST "http://localhost:$HOST_PORT/getBrowser" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{}') | |
| if echo "$browser_response" | grep -q "browserId"; then | |
| log_success "β Browser allocation successful" | |
| # Extract browser ID | |
| local browser_id | |
| browser_id=$(echo "$browser_response" | grep -o '"browserId":"[^"]*"' | cut -d'"' -f4) | |
| log_info "Allocated browser ID: $browser_id" | |
| # Test 3: Page navigation test | |
| log_info "Test 3: Page navigation test (baidu.com)" | |
| local page_response | |
| page_response=$(curl -s -X POST "http://localhost:$HOST_PORT/openPage" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"browserId\":\"$browser_id\", \"url\":\"https://www.baidu.com\"}") | |
| if echo "$page_response" | grep -q "pageId"; then | |
| local page_id | |
| page_id=$(echo "$page_response" | grep -o '"pageId":"[^"]*"' | cut -d'"' -f4) | |
| log_success "β Page navigation successful" | |
| log_info "Page ID: $page_id" | |
| # Test 4: Get page content | |
| log_info "Test 4: Get page content test" | |
| local content_response | |
| content_response=$(curl -s -X POST "http://localhost:$HOST_PORT/gethtmlcontent" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"browserId\":\"$browser_id\", \"pageId\":\"$page_id\"}") | |
| if echo "$content_response" | grep -q "html"; then | |
| log_success "β Page content retrieval successful" | |
| else | |
| log_warn "β Page content retrieval completed (limited response)" | |
| fi | |
| else | |
| log_warn "β Page navigation test completed (response: $page_response)" | |
| fi | |
| # Test 5: Browser closure (final cleanup) | |
| log_info "Test 5: Browser closure test" | |
| local close_response | |
| close_response=$(curl -s -X POST "http://localhost:$HOST_PORT/closeBrowser" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"browserId\":\"$browser_id\"}") | |
| if echo "$close_response" | grep -q "successfully"; then | |
| log_success "β Browser closure test completed" | |
| else | |
| log_warn "β Browser closure test completed (response: $close_response)" | |
| fi | |
| else | |
| log_error "β Browser allocation failed" | |
| log_error "Response: $browser_response" | |
| return 1 | |
| fi | |
| # Show container status | |
| log_info "Container running status:" | |
| $DOCKER_CMD ps --filter "name=$CONTAINER_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | |
| log_success "All verification tests passed!" | |
| echo "" | |
| echo "============================================" | |
| echo "Container Verification Complete" | |
| echo "============================================" | |
| echo "Container name: $CONTAINER_NAME" | |
| echo "Access URL: http://localhost:$HOST_PORT" | |
| echo "Health check: http://localhost:$HOST_PORT/health" | |
| echo "" | |
| echo "Verified functionality (5 tests):" | |
| echo " β Test 1: Health check endpoint" | |
| echo " β Test 2: Browser allocation and management" | |
| echo " β Test 3: Page navigation (baidu.com)" | |
| echo " β Test 4: HTML content retrieval" | |
| echo " β Test 5: Browser cleanup and closure" | |
| echo "" | |
| echo "Common commands:" | |
| echo " View logs: $DOCKER_CMD logs $CONTAINER_NAME" | |
| echo " Stop container: $DOCKER_CMD stop $CONTAINER_NAME" | |
| echo " Remove container: $DOCKER_CMD rm $CONTAINER_NAME" | |
| echo " Enter container: $DOCKER_CMD exec -it $CONTAINER_NAME /bin/bash" | |
| echo "" | |
| echo "If using sudo docker, remember to add sudo before commands" | |
| echo "============================================" | |
| } | |
| # Main function | |
| main() { | |
| echo "============================================" | |
| echo "CognitiveKernel-Pro Web Server Auto Build" | |
| echo "============================================" | |
| echo "Features: Auto-install Docker, build image, start container, verify service" | |
| echo "Location: $(pwd)" | |
| echo "Docker command: $DOCKER_CMD" | |
| echo "============================================" | |
| echo "" | |
| # Check dependencies (includes auto Docker installation) | |
| check_dependencies | |
| # Build image | |
| build_image | |
| # Start container | |
| start_container | |
| # Wait for service to start | |
| if wait_for_service; then | |
| # Verify container | |
| verify_container | |
| else | |
| log_error "Service startup failed, skipping verification" | |
| log_info "View container logs:" | |
| $DOCKER_CMD logs "$CONTAINER_NAME" 2>/dev/null || true | |
| exit 1 | |
| fi | |
| } | |
| # Show usage instructions | |
| show_usage() { | |
| echo "Usage Instructions:" | |
| echo "1. Ensure running this script in ck_pro/ck_web/_web/ directory" | |
| echo "2. Script will auto-detect and install Docker (Linux systems)" | |
| echo "3. For regular users, will automatically use sudo docker commands" | |
| echo "4. After build completion, will auto-start container and verify service" | |
| echo "" | |
| echo "Run command:" | |
| echo " cd ck_pro/ck_web/_web/" | |
| echo " ./build-web-server.sh" | |
| echo "" | |
| } | |
| # Check script location | |
| check_script_location() { | |
| if [[ ! -f "Dockerfile" ]] || [[ ! -f "server.js" ]]; then | |
| log_error "Incorrect script location!" | |
| echo "" | |
| show_usage | |
| exit 1 | |
| fi | |
| } | |
| # Execute main function | |
| if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then | |
| check_script_location | |
| main "$@" | |
| fi | |