#!/bin/bash
# Build script for ComfyUI Docker containers with BuildKit optimizations
set -euo pipefail
# 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
PROJECT_NAME="${PROJECT_NAME:-mcp-comfyui-flux}"
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
ENABLE_BUILDKIT="${ENABLE_BUILDKIT:-1}"
MEASURE_TIME="${MEASURE_TIME:-1}"
# Build arguments
USER_ID="${USER_ID:-$(id -u)}"
GROUP_ID="${GROUP_ID:-$(id -g)}"
# Function to print colored output
log() {
local color=$1
shift
echo -e "${color}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $*"
}
# Function to measure build time
measure_time() {
local start_time=$1
local end_time=$(date +%s)
local duration=$((end_time - start_time))
local minutes=$((duration / 60))
local seconds=$((duration % 60))
echo "${minutes}m ${seconds}s"
}
# Function to get image sizes
get_image_sizes() {
log $BLUE "Image sizes:"
docker images | grep -E "(mcp-comfyui|REPOSITORY)" | awk '{printf " %-40s %s\n", $1":"$2, $7}'
}
# Check prerequisites
check_prerequisites() {
log $BLUE "Checking prerequisites..."
if ! command -v docker &> /dev/null; then
log $RED "Docker is not installed!"
exit 1
fi
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
log $RED "Docker Compose is not installed!"
exit 1
fi
if [[ "$ENABLE_BUILDKIT" == "1" ]]; then
export DOCKER_BUILDKIT=1
log $GREEN "BuildKit enabled"
fi
# Check available disk space
available_space=$(df -h . | awk 'NR==2 {print $4}')
log $BLUE "Available disk space: $available_space"
# Check WSL2 memory if applicable
if [[ -f /proc/sys/fs/binfmt_misc/WSLInterop ]]; then
total_memory=$(free -h | awk 'NR==2 {print $2}')
available_memory=$(free -h | awk 'NR==2 {print $7}')
log $BLUE "WSL2 detected. Memory - Total: $total_memory, Available: $available_memory"
fi
}
# Build containers
build_containers() {
log $GREEN "Starting Docker build..."
local start_time=$(date +%s)
# Export build args for docker-compose
export USER_ID
export GROUP_ID
# Build with docker-compose
if docker compose version &> /dev/null; then
docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" build
else
docker-compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" build
fi
local build_result=$?
if [[ $build_result -eq 0 ]]; then
log $GREEN "Build completed successfully!"
if [[ "$MEASURE_TIME" == "1" ]]; then
local duration=$(measure_time $start_time)
log $GREEN "Build time: $duration"
fi
else
log $RED "Build failed!"
return 1
fi
}
# Start containers
start_containers() {
if [[ "${START_AFTER_BUILD:-0}" == "1" ]]; then
log $BLUE "Starting containers..."
if docker compose version &> /dev/null; then
docker compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" up -d
else
docker-compose -p "$PROJECT_NAME" -f "$COMPOSE_FILE" up -d
fi
if [[ $? -eq 0 ]]; then
log $GREEN "Containers started successfully!"
log $BLUE "ComfyUI available at: http://localhost:8188"
log $BLUE "To view logs: docker-compose -p $PROJECT_NAME logs -f"
else
log $RED "Failed to start containers!"
return 1
fi
fi
}
# Clean up old images
cleanup() {
if [[ "${CLEANUP:-0}" == "1" ]]; then
log $YELLOW "Cleaning up dangling images..."
docker image prune -f
log $GREEN "Cleanup completed"
fi
}
# Show container status
show_status() {
log $BLUE "Container status:"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "(NAME|$PROJECT_NAME)"
}
# Main execution
main() {
log $GREEN "=== Starting ComfyUI Docker Build ==="
check_prerequisites
if build_containers; then
get_image_sizes
start_containers
cleanup
if [[ "${START_AFTER_BUILD:-0}" == "1" ]]; then
show_status
fi
log $GREEN "=== Build completed successfully! ==="
if [[ "${START_AFTER_BUILD:-0}" != "1" ]]; then
log $BLUE "To start the containers: docker-compose -p $PROJECT_NAME up -d"
fi
else
log $RED "=== Build failed! ==="
exit 1
fi
}
# Handle script arguments
while [[ $# -gt 0 ]]; do
case $1 in
--start)
START_AFTER_BUILD=1
shift
;;
--cleanup)
CLEANUP=1
shift
;;
--no-buildkit)
ENABLE_BUILDKIT=0
shift
;;
--no-cache)
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
export BUILDKIT_PROGRESS=plain
docker compose -p "$PROJECT_NAME" build --no-cache
exit $?
;;
--help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Build ComfyUI Docker containers with optimizations"
echo ""
echo "Options:"
echo " --start Start containers after successful build"
echo " --cleanup Clean up dangling images after build"
echo " --no-buildkit Disable BuildKit optimizations"
echo " --no-cache Build without using cache"
echo " --help Show this help message"
echo ""
echo "Environment variables:"
echo " USER_ID User ID for container (default: current user)"
echo " GROUP_ID Group ID for container (default: current group)"
echo " PROJECT_NAME Docker project name (default: mcp-comfyui)"
echo ""
echo "Examples:"
echo " $0 # Build only"
echo " $0 --start # Build and start containers"
echo " $0 --start --cleanup # Build, start, and cleanup"
echo " $0 --no-cache # Rebuild from scratch"
exit 0
;;
*)
log $RED "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Run main function
main