optimize for rpi
This commit is contained in:
		
							
								
								
									
										257
									
								
								build-pi.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										257
									
								
								build-pi.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,257 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# Build script for Raspberry Pi Zero/ARM devices
 | 
			
		||||
# Optimized for low memory and no compilation
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
IMAGE_NAME="turmli-calendar"
 | 
			
		||||
CONTAINER_NAME="turmli-calendar"
 | 
			
		||||
 | 
			
		||||
# Print functions
 | 
			
		||||
print_error() {
 | 
			
		||||
    echo -e "${RED}❌ $1${NC}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print_success() {
 | 
			
		||||
    echo -e "${GREEN}✅ $1${NC}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print_info() {
 | 
			
		||||
    echo -e "${BLUE}ℹ️  $1${NC}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print_warning() {
 | 
			
		||||
    echo -e "${YELLOW}⚠️  $1${NC}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Detect system
 | 
			
		||||
detect_system() {
 | 
			
		||||
    ARCH=$(uname -m)
 | 
			
		||||
    OS=$(cat /etc/os-release | grep "^ID=" | cut -d= -f2 | tr -d '"')
 | 
			
		||||
    VERSION=$(cat /etc/os-release | grep "^VERSION_CODENAME=" | cut -d= -f2 | tr -d '"')
 | 
			
		||||
    
 | 
			
		||||
    print_info "System: ${OS} ${VERSION} on ${ARCH}"
 | 
			
		||||
    
 | 
			
		||||
    # Check if we're on a Raspberry Pi
 | 
			
		||||
    if [ -f /proc/device-tree/model ]; then
 | 
			
		||||
        MODEL=$(tr -d '\0' < /proc/device-tree/model)
 | 
			
		||||
        print_info "Raspberry Pi detected: ${MODEL}"
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Check available memory
 | 
			
		||||
    if [ -f /proc/meminfo ]; then
 | 
			
		||||
        TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')
 | 
			
		||||
        TOTAL_MEM_MB=$((TOTAL_MEM / 1024))
 | 
			
		||||
        print_info "Available RAM: ${TOTAL_MEM_MB}MB"
 | 
			
		||||
        
 | 
			
		||||
        if [ $TOTAL_MEM_MB -lt 512 ]; then
 | 
			
		||||
            print_warning "Low memory detected! Build may be slow."
 | 
			
		||||
            print_info "Tip: Consider adding swap space if build fails"
 | 
			
		||||
        fi
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Check for container runtime
 | 
			
		||||
check_runtime() {
 | 
			
		||||
    if command -v podman &> /dev/null; then
 | 
			
		||||
        RUNTIME="podman"
 | 
			
		||||
        print_success "Using Podman"
 | 
			
		||||
    elif command -v docker &> /dev/null; then
 | 
			
		||||
        RUNTIME="docker"
 | 
			
		||||
        print_success "Using Docker"
 | 
			
		||||
    else
 | 
			
		||||
        print_error "No container runtime found!"
 | 
			
		||||
        print_info "Install Podman (recommended) or Docker:"
 | 
			
		||||
        echo "  sudo apt-get update"
 | 
			
		||||
        echo "  sudo apt-get install podman"
 | 
			
		||||
        exit 1
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Build the container
 | 
			
		||||
build_container() {
 | 
			
		||||
    print_info "Building container image..."
 | 
			
		||||
    
 | 
			
		||||
    # Choose the right Dockerfile
 | 
			
		||||
    if [ -f "Dockerfile.pizero" ] && [[ "$ARCH" == "armv6l" ]]; then
 | 
			
		||||
        DOCKERFILE="Dockerfile.pizero"
 | 
			
		||||
        print_info "Using Pi Zero optimized Dockerfile"
 | 
			
		||||
    elif [ -f "Dockerfile.minimal" ]; then
 | 
			
		||||
        DOCKERFILE="Dockerfile.minimal"
 | 
			
		||||
        print_info "Using minimal Dockerfile (no compilation)"
 | 
			
		||||
    elif [ -f "Dockerfile" ]; then
 | 
			
		||||
        DOCKERFILE="Dockerfile"
 | 
			
		||||
        print_warning "Using standard Dockerfile (may require compilation)"
 | 
			
		||||
    else
 | 
			
		||||
        print_error "No Dockerfile found!"
 | 
			
		||||
        exit 1
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Build with memory limits for Pi Zero
 | 
			
		||||
    if [[ "$ARCH" == "armv6l" ]] && [ $TOTAL_MEM_MB -lt 512 ]; then
 | 
			
		||||
        print_warning "Building with memory constraints..."
 | 
			
		||||
        ${RUNTIME} build \
 | 
			
		||||
            --memory-swap -1 \
 | 
			
		||||
            --file "${DOCKERFILE}" \
 | 
			
		||||
            --tag "${IMAGE_NAME}" \
 | 
			
		||||
            . || {
 | 
			
		||||
            print_error "Build failed!"
 | 
			
		||||
            print_info "Try these solutions:"
 | 
			
		||||
            echo "  1. Add swap space:"
 | 
			
		||||
            echo "     sudo dd if=/dev/zero of=/swapfile bs=1M count=1024"
 | 
			
		||||
            echo "     sudo mkswap /swapfile"
 | 
			
		||||
            echo "     sudo swapon /swapfile"
 | 
			
		||||
            echo "  2. Use pre-built image:"
 | 
			
		||||
            echo "     ${RUNTIME} pull docker.io/yourusername/turmli-calendar:armv6"
 | 
			
		||||
            exit 1
 | 
			
		||||
        }
 | 
			
		||||
    else
 | 
			
		||||
        ${RUNTIME} build \
 | 
			
		||||
            --file "${DOCKERFILE}" \
 | 
			
		||||
            --tag "${IMAGE_NAME}" \
 | 
			
		||||
            . || {
 | 
			
		||||
            print_error "Build failed!"
 | 
			
		||||
            exit 1
 | 
			
		||||
        }
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    print_success "Container image built successfully!"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Run the container
 | 
			
		||||
run_container() {
 | 
			
		||||
    print_info "Starting container..."
 | 
			
		||||
    
 | 
			
		||||
    # Check if container already exists
 | 
			
		||||
    if ${RUNTIME} ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
 | 
			
		||||
        print_info "Container already exists, removing it..."
 | 
			
		||||
        ${RUNTIME} stop ${CONTAINER_NAME} 2>/dev/null || true
 | 
			
		||||
        ${RUNTIME} rm ${CONTAINER_NAME} 2>/dev/null || true
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Create cache file if it doesn't exist
 | 
			
		||||
    if [ ! -f "calendar_cache.json" ]; then
 | 
			
		||||
        echo "{}" > calendar_cache.json
 | 
			
		||||
        print_info "Created cache file"
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Run with appropriate resource limits for Pi
 | 
			
		||||
    if [[ "$ARCH" == "armv6l" ]] && [ $TOTAL_MEM_MB -lt 512 ]; then
 | 
			
		||||
        print_info "Running with memory constraints..."
 | 
			
		||||
        ${RUNTIME} run -d \
 | 
			
		||||
            --name ${CONTAINER_NAME} \
 | 
			
		||||
            --memory 256m \
 | 
			
		||||
            --memory-swap -1 \
 | 
			
		||||
            -p 8000:8000 \
 | 
			
		||||
            -v $(pwd)/calendar_cache.json:/app/calendar_cache.json:Z \
 | 
			
		||||
            -e TZ=Europe/Berlin \
 | 
			
		||||
            --restart unless-stopped \
 | 
			
		||||
            ${IMAGE_NAME}
 | 
			
		||||
    else
 | 
			
		||||
        ${RUNTIME} run -d \
 | 
			
		||||
            --name ${CONTAINER_NAME} \
 | 
			
		||||
            -p 8000:8000 \
 | 
			
		||||
            -v $(pwd)/calendar_cache.json:/app/calendar_cache.json:Z \
 | 
			
		||||
            -e TZ=Europe/Berlin \
 | 
			
		||||
            --restart unless-stopped \
 | 
			
		||||
            ${IMAGE_NAME}
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    print_success "Container started!"
 | 
			
		||||
    print_info "Access the calendar at: http://$(hostname -I | awk '{print $1}'):8000"
 | 
			
		||||
    print_info "or http://localhost:8000"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Check container status
 | 
			
		||||
check_status() {
 | 
			
		||||
    print_info "Checking container status..."
 | 
			
		||||
    
 | 
			
		||||
    if ${RUNTIME} ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -q ${CONTAINER_NAME}; then
 | 
			
		||||
        ${RUNTIME} ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "NAMES|${CONTAINER_NAME}"
 | 
			
		||||
        
 | 
			
		||||
        # Test if the app is responding
 | 
			
		||||
        print_info "Testing application..."
 | 
			
		||||
        sleep 3
 | 
			
		||||
        if curl -s -f http://localhost:8000/api/events > /dev/null 2>&1; then
 | 
			
		||||
            print_success "Application is running and healthy!"
 | 
			
		||||
        else
 | 
			
		||||
            print_warning "Application not responding yet, checking logs..."
 | 
			
		||||
            ${RUNTIME} logs --tail 20 ${CONTAINER_NAME}
 | 
			
		||||
        fi
 | 
			
		||||
    else
 | 
			
		||||
        print_warning "Container is not running"
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Show logs
 | 
			
		||||
show_logs() {
 | 
			
		||||
    ${RUNTIME} logs -f ${CONTAINER_NAME}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Main script
 | 
			
		||||
case "${1:-build}" in
 | 
			
		||||
    build)
 | 
			
		||||
        detect_system
 | 
			
		||||
        check_runtime
 | 
			
		||||
        build_container
 | 
			
		||||
        ;;
 | 
			
		||||
    run)
 | 
			
		||||
        detect_system
 | 
			
		||||
        check_runtime
 | 
			
		||||
        run_container
 | 
			
		||||
        check_status
 | 
			
		||||
        ;;
 | 
			
		||||
    start)
 | 
			
		||||
        detect_system
 | 
			
		||||
        check_runtime
 | 
			
		||||
        build_container
 | 
			
		||||
        run_container
 | 
			
		||||
        check_status
 | 
			
		||||
        ;;
 | 
			
		||||
    status)
 | 
			
		||||
        check_runtime
 | 
			
		||||
        check_status
 | 
			
		||||
        ;;
 | 
			
		||||
    logs)
 | 
			
		||||
        check_runtime
 | 
			
		||||
        show_logs
 | 
			
		||||
        ;;
 | 
			
		||||
    stop)
 | 
			
		||||
        check_runtime
 | 
			
		||||
        print_info "Stopping container..."
 | 
			
		||||
        ${RUNTIME} stop ${CONTAINER_NAME}
 | 
			
		||||
        print_success "Container stopped"
 | 
			
		||||
        ;;
 | 
			
		||||
    help)
 | 
			
		||||
        echo "Raspberry Pi Build Script for Turmli Calendar"
 | 
			
		||||
        echo ""
 | 
			
		||||
        echo "Usage: $0 [COMMAND]"
 | 
			
		||||
        echo ""
 | 
			
		||||
        echo "Commands:"
 | 
			
		||||
        echo "  build   - Build the container image (default)"
 | 
			
		||||
        echo "  run     - Run the container"
 | 
			
		||||
        echo "  start   - Build and run"
 | 
			
		||||
        echo "  status  - Check container status"
 | 
			
		||||
        echo "  logs    - Show container logs"
 | 
			
		||||
        echo "  stop    - Stop the container"
 | 
			
		||||
        echo "  help    - Show this help"
 | 
			
		||||
        echo ""
 | 
			
		||||
        echo "This script is optimized for Raspberry Pi Zero and other"
 | 
			
		||||
        echo "low-resource ARM devices. It uses Pydantic v1 to avoid"
 | 
			
		||||
        echo "Rust compilation requirements."
 | 
			
		||||
        ;;
 | 
			
		||||
    *)
 | 
			
		||||
        echo "Unknown command: $1"
 | 
			
		||||
        echo "Run '$0 help' for usage"
 | 
			
		||||
        exit 1
 | 
			
		||||
        ;;
 | 
			
		||||
esac
 | 
			
		||||
		Reference in New Issue
	
	Block a user