Slimming down
This commit is contained in:
		
							
								
								
									
										300
									
								
								build-container.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										300
									
								
								build-container.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,300 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# Smart container build script for Turmli Bar Calendar
 | 
			
		||||
# Automatically detects architecture and chooses the best build strategy
 | 
			
		||||
 | 
			
		||||
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="${IMAGE_NAME:-turmli-calendar}"
 | 
			
		||||
BUILD_TYPE=""
 | 
			
		||||
RUNTIME=""
 | 
			
		||||
 | 
			
		||||
# 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 container runtime
 | 
			
		||||
detect_runtime() {
 | 
			
		||||
    if command -v podman &> /dev/null; then
 | 
			
		||||
        RUNTIME="podman"
 | 
			
		||||
        print_info "Using Podman"
 | 
			
		||||
    elif command -v docker &> /dev/null; then
 | 
			
		||||
        RUNTIME="docker"
 | 
			
		||||
        print_info "Using Docker"
 | 
			
		||||
    else
 | 
			
		||||
        print_error "No container runtime found. Please install Podman or Docker."
 | 
			
		||||
        exit 1
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Detect architecture and choose build strategy
 | 
			
		||||
detect_architecture() {
 | 
			
		||||
    ARCH=$(uname -m)
 | 
			
		||||
    OS=$(uname -s)
 | 
			
		||||
    
 | 
			
		||||
    print_info "System: ${OS} ${ARCH}"
 | 
			
		||||
    
 | 
			
		||||
    case "${ARCH}" in
 | 
			
		||||
        armv6l|armv7l)
 | 
			
		||||
            print_info "ARM 32-bit detected (Raspberry Pi)"
 | 
			
		||||
            BUILD_TYPE="arm"
 | 
			
		||||
            ;;
 | 
			
		||||
        aarch64|arm64)
 | 
			
		||||
            print_info "ARM 64-bit detected"
 | 
			
		||||
            BUILD_TYPE="arm"
 | 
			
		||||
            ;;
 | 
			
		||||
        x86_64|amd64)
 | 
			
		||||
            print_info "x86_64 detected"
 | 
			
		||||
            BUILD_TYPE="standard"
 | 
			
		||||
            ;;
 | 
			
		||||
        *)
 | 
			
		||||
            print_warning "Unknown architecture: ${ARCH}"
 | 
			
		||||
            BUILD_TYPE="standard"
 | 
			
		||||
            ;;
 | 
			
		||||
    esac
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Check if we have enough memory for build
 | 
			
		||||
check_memory() {
 | 
			
		||||
    if [ -f /proc/meminfo ]; then
 | 
			
		||||
        TOTAL_MEM=$(grep MemTotal /proc/meminfo | awk '{print $2}')
 | 
			
		||||
        TOTAL_MEM_MB=$((TOTAL_MEM / 1024))
 | 
			
		||||
        
 | 
			
		||||
        if [ $TOTAL_MEM_MB -lt 512 ]; then
 | 
			
		||||
            print_warning "Low memory detected: ${TOTAL_MEM_MB}MB"
 | 
			
		||||
            print_warning "Build may fail. Consider using pre-built images or increasing swap."
 | 
			
		||||
            
 | 
			
		||||
            # Check swap
 | 
			
		||||
            SWAP=$(grep SwapTotal /proc/meminfo | awk '{print $2}')
 | 
			
		||||
            SWAP_MB=$((SWAP / 1024))
 | 
			
		||||
            if [ $SWAP_MB -lt 1024 ]; then
 | 
			
		||||
                print_warning "Swap is low: ${SWAP_MB}MB. Consider adding swap space:"
 | 
			
		||||
                echo "  sudo dd if=/dev/zero of=/swapfile bs=1G count=2"
 | 
			
		||||
                echo "  sudo mkswap /swapfile"
 | 
			
		||||
                echo "  sudo swapon /swapfile"
 | 
			
		||||
            fi
 | 
			
		||||
        else
 | 
			
		||||
            print_info "Memory: ${TOTAL_MEM_MB}MB"
 | 
			
		||||
        fi
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Build for ARM architecture
 | 
			
		||||
build_arm() {
 | 
			
		||||
    print_info "Building for ARM architecture..."
 | 
			
		||||
    
 | 
			
		||||
    # Check which Dockerfile to use
 | 
			
		||||
    if [ -f "Dockerfile.arm" ]; then
 | 
			
		||||
        print_info "Using ARM-optimized Dockerfile"
 | 
			
		||||
        DOCKERFILE="Dockerfile.arm"
 | 
			
		||||
    else
 | 
			
		||||
        print_warning "Dockerfile.arm not found, using standard Dockerfile"
 | 
			
		||||
        print_warning "This may take longer and require more memory"
 | 
			
		||||
        DOCKERFILE="Dockerfile"
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Check if requirements-arm.txt exists
 | 
			
		||||
    if [ -f "requirements-arm.txt" ] && [ -f "Dockerfile.arm" ]; then
 | 
			
		||||
        print_info "Using simplified requirements for ARM"
 | 
			
		||||
    elif [ -f "requirements-arm.txt" ]; then
 | 
			
		||||
        print_warning "Found requirements-arm.txt but no Dockerfile.arm"
 | 
			
		||||
        print_info "Consider creating Dockerfile.arm for better ARM support"
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Build with limited parallelism on ARM to save memory
 | 
			
		||||
    print_info "Building with limited parallelism to save memory..."
 | 
			
		||||
    export CARGO_BUILD_JOBS=1
 | 
			
		||||
    export MAKEFLAGS="-j1"
 | 
			
		||||
    
 | 
			
		||||
    ${RUNTIME} build \
 | 
			
		||||
        --file "${DOCKERFILE}" \
 | 
			
		||||
        --tag "${IMAGE_NAME}" \
 | 
			
		||||
        --memory-swap -1 \
 | 
			
		||||
        . || {
 | 
			
		||||
        print_error "Build failed!"
 | 
			
		||||
        print_info "Troubleshooting tips:"
 | 
			
		||||
        echo "  1. Try increasing swap space"
 | 
			
		||||
        echo "  2. Use Dockerfile.arm with requirements-arm.txt"
 | 
			
		||||
        echo "  3. Build on a more powerful machine and transfer the image"
 | 
			
		||||
        exit 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Build for standard architecture
 | 
			
		||||
build_standard() {
 | 
			
		||||
    print_info "Building for standard architecture..."
 | 
			
		||||
    
 | 
			
		||||
    # Choose Dockerfile
 | 
			
		||||
    if [ "$RUNTIME" = "podman" ] && [ -f "Containerfile" ]; then
 | 
			
		||||
        DOCKERFILE="Containerfile"
 | 
			
		||||
    elif [ -f "Dockerfile" ]; then
 | 
			
		||||
        DOCKERFILE="Dockerfile"
 | 
			
		||||
    else
 | 
			
		||||
        print_error "No Dockerfile found!"
 | 
			
		||||
        exit 1
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    print_info "Using ${DOCKERFILE}"
 | 
			
		||||
    
 | 
			
		||||
    ${RUNTIME} build \
 | 
			
		||||
        --file "${DOCKERFILE}" \
 | 
			
		||||
        --tag "${IMAGE_NAME}" \
 | 
			
		||||
        . || {
 | 
			
		||||
        print_error "Build failed!"
 | 
			
		||||
        exit 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Build with cache mount (if supported)
 | 
			
		||||
build_with_cache() {
 | 
			
		||||
    print_info "Attempting build with cache mount..."
 | 
			
		||||
    
 | 
			
		||||
    # Check if BuildKit is available (Docker) or if Podman supports cache mounts
 | 
			
		||||
    if [ "$RUNTIME" = "docker" ]; then
 | 
			
		||||
        export DOCKER_BUILDKIT=1
 | 
			
		||||
        CACHE_OPT="--mount=type=cache,target=/root/.cache/pip"
 | 
			
		||||
    elif [ "$RUNTIME" = "podman" ]; then
 | 
			
		||||
        # Podman 4.1+ supports cache mounts
 | 
			
		||||
        CACHE_OPT="--mount=type=cache,target=/root/.cache/pip"
 | 
			
		||||
    else
 | 
			
		||||
        CACHE_OPT=""
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    # Attempt build with cache
 | 
			
		||||
    if [ -n "$CACHE_OPT" ]; then
 | 
			
		||||
        print_info "Using build cache for faster rebuilds"
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    if [ "$BUILD_TYPE" = "arm" ]; then
 | 
			
		||||
        build_arm
 | 
			
		||||
    else
 | 
			
		||||
        build_standard
 | 
			
		||||
    fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Clean build (no cache)
 | 
			
		||||
clean_build() {
 | 
			
		||||
    print_info "Performing clean build (no cache)..."
 | 
			
		||||
    
 | 
			
		||||
    ${RUNTIME} build \
 | 
			
		||||
        --no-cache \
 | 
			
		||||
        --file "${DOCKERFILE:-Dockerfile}" \
 | 
			
		||||
        --tag "${IMAGE_NAME}" \
 | 
			
		||||
        . || {
 | 
			
		||||
        print_error "Build failed!"
 | 
			
		||||
        exit 1
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Show build information
 | 
			
		||||
show_info() {
 | 
			
		||||
    echo -e "${BLUE}Build Configuration:${NC}"
 | 
			
		||||
    echo "  Runtime: ${RUNTIME}"
 | 
			
		||||
    echo "  Architecture: $(uname -m)"
 | 
			
		||||
    echo "  Build Type: ${BUILD_TYPE}"
 | 
			
		||||
    echo "  Image Name: ${IMAGE_NAME}"
 | 
			
		||||
    
 | 
			
		||||
    if [ "$BUILD_TYPE" = "arm" ]; then
 | 
			
		||||
        echo ""
 | 
			
		||||
        echo -e "${YELLOW}ARM Build Notes:${NC}"
 | 
			
		||||
        echo "  - Uses simplified dependencies where possible"
 | 
			
		||||
        echo "  - Avoids packages requiring Rust compilation"
 | 
			
		||||
        echo "  - May have slightly reduced performance"
 | 
			
		||||
        echo "  - Optimized for low memory usage"
 | 
			
		||||
    fi
 | 
			
		||||
    
 | 
			
		||||
    echo ""
 | 
			
		||||
    print_info "Checking available Dockerfiles..."
 | 
			
		||||
    for file in Dockerfile Containerfile Dockerfile.arm; do
 | 
			
		||||
        if [ -f "$file" ]; then
 | 
			
		||||
            print_success "$file found"
 | 
			
		||||
        fi
 | 
			
		||||
    done
 | 
			
		||||
    
 | 
			
		||||
    echo ""
 | 
			
		||||
    print_info "Checking requirements files..."
 | 
			
		||||
    for file in requirements.txt requirements-arm.txt; do
 | 
			
		||||
        if [ -f "$file" ]; then
 | 
			
		||||
            print_success "$file found"
 | 
			
		||||
        fi
 | 
			
		||||
    done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Main function
 | 
			
		||||
main() {
 | 
			
		||||
    case "${1:-}" in
 | 
			
		||||
        --clean)
 | 
			
		||||
            detect_runtime
 | 
			
		||||
            detect_architecture
 | 
			
		||||
            clean_build
 | 
			
		||||
            ;;
 | 
			
		||||
        --info)
 | 
			
		||||
            detect_runtime
 | 
			
		||||
            detect_architecture
 | 
			
		||||
            check_memory
 | 
			
		||||
            show_info
 | 
			
		||||
            ;;
 | 
			
		||||
        --help)
 | 
			
		||||
            echo "Smart Container Build Script for Turmli Bar Calendar"
 | 
			
		||||
            echo ""
 | 
			
		||||
            echo "Usage: $0 [OPTIONS]"
 | 
			
		||||
            echo ""
 | 
			
		||||
            echo "Options:"
 | 
			
		||||
            echo "  --clean   Perform a clean build (no cache)"
 | 
			
		||||
            echo "  --info    Show build configuration and system info"
 | 
			
		||||
            echo "  --help    Show this help message"
 | 
			
		||||
            echo ""
 | 
			
		||||
            echo "Environment Variables:"
 | 
			
		||||
            echo "  IMAGE_NAME    Name for the built image (default: turmli-calendar)"
 | 
			
		||||
            echo ""
 | 
			
		||||
            echo "The script automatically detects:"
 | 
			
		||||
            echo "  - Container runtime (Podman/Docker)"
 | 
			
		||||
            echo "  - System architecture (ARM/x86_64)"
 | 
			
		||||
            echo "  - Available memory"
 | 
			
		||||
            echo "  - Best Dockerfile to use"
 | 
			
		||||
            ;;
 | 
			
		||||
        *)
 | 
			
		||||
            detect_runtime
 | 
			
		||||
            detect_architecture
 | 
			
		||||
            check_memory
 | 
			
		||||
            
 | 
			
		||||
            print_info "Starting build process..."
 | 
			
		||||
            
 | 
			
		||||
            if [ "$BUILD_TYPE" = "arm" ]; then
 | 
			
		||||
                build_arm
 | 
			
		||||
            else
 | 
			
		||||
                build_standard
 | 
			
		||||
            fi
 | 
			
		||||
            
 | 
			
		||||
            if [ $? -eq 0 ]; then
 | 
			
		||||
                print_success "Build completed successfully!"
 | 
			
		||||
                print_info "Image: ${IMAGE_NAME}"
 | 
			
		||||
                print_info "Run with: ${RUNTIME} run -d -p 8000:8000 ${IMAGE_NAME}"
 | 
			
		||||
            fi
 | 
			
		||||
            ;;
 | 
			
		||||
    esac
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Run main function
 | 
			
		||||
main "$@"
 | 
			
		||||
		Reference in New Issue
	
	Block a user