#!/bin/bash # ============================================================================ # 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