#!/bin/bash # 最终版离线构建脚本 - 使用预装 APT 包的基础镜像 # Usage: ./build-offline-final.sh [cache-dir] [version] set -e CACHE_DIR="${1:-./build-cache}" VERSION="${2:-latest}" IMAGES_DIR="$CACHE_DIR/images" RESOURCES_DIR="$CACHE_DIR/resources" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # 检查缓存目录 if [ ! -d "$CACHE_DIR" ]; then log_error "缓存目录 $CACHE_DIR 不存在" exit 1 fi # 加载基础镜像 load_images() { log_info "加载基础镜像..." # 优先加载带 APT 预装包的镜像集合 if [ -f "$IMAGES_DIR/base-images-with-apt.tar" ]; then log_info "加载带 APT 预装包的基础镜像..." docker load -i "$IMAGES_DIR/base-images-with-apt.tar" elif [ -f "$IMAGES_DIR/base-images.tar" ]; then log_warn "加载普通基础镜像(不含 APT 预装包)..." docker load -i "$IMAGES_DIR/base-images.tar" else log_warn "基础镜像 tar 包不存在,检查本地镜像..." fi log_info "✓ 镜像加载完成" } # 验证镜像是否存在 verify_image() { docker inspect "$1" > /dev/null 2>&1 } # 构建函数 build_service() { local service_name=$1 local image_name=$2 local dockerfile=$3 local base_image=$4 # 必需的基础镜像 log_info "----------------------------------------" log_info "构建 $service_name" log_info "----------------------------------------" if [ ! -f "$dockerfile" ]; then log_error "Dockerfile 不存在: $dockerfile" return 1 fi # 检查必需的基础镜像 if [ -n "$base_image" ]; then if verify_image "$base_image"; then log_info "✓ 基础镜像存在: $base_image" else log_error "✗ 缺少基础镜像: $base_image" log_info "请确保已加载正确的 base-images-with-apt.tar" return 1 fi fi # 准备构建参数 local build_args=() # 添加资源目录参数 if [ -d "$RESOURCES_DIR" ]; then build_args+=("--build-arg" "RESOURCES_DIR=$RESOURCES_DIR") fi # 执行构建 log_info "开始构建..." if docker build \ --pull=false \ "${build_args[@]}" \ -f "$dockerfile" \ -t "$image_name:$VERSION" \ . 2>&1; then log_info "✓ $service_name 构建成功" return 0 else log_error "✗ $service_name 构建失败" return 1 fi } # 主流程 main() { log_info "======================================" log_info "最终版离线构建 (使用 APT 预装基础镜像)" log_info "======================================" # 加载基础镜像 load_images # 验证关键基础镜像 log_info "" log_info "验证预装基础镜像..." REQUIRED_BASE_IMAGES=( "datamate-java-base:latest" "datamate-python-base:latest" "datamate-runtime-base:latest" ) for img in "${REQUIRED_BASE_IMAGES[@]}"; do if verify_image "$img"; then log_info " ✓ $img" else log_warn " ✗ $img (缺失)" fi done # 定义服务配置 declare -A SERVICES=( ["database"]="datamate-database:scripts/images/database/Dockerfile:" ["gateway"]="datamate-gateway:scripts/offline/Dockerfile.gateway.offline:datamate-java-base:latest" ["backend"]="datamate-backend:scripts/offline/Dockerfile.backend.offline:datamate-java-base:latest" ["frontend"]="datamate-frontend:scripts/images/frontend/Dockerfile:" ["runtime"]="datamate-runtime:scripts/offline/Dockerfile.runtime.offline-v2:datamate-runtime-base:latest" ["backend-python"]="datamate-backend-python:scripts/offline/Dockerfile.backend-python.offline-v2:datamate-python-base:latest" ) log_info "" log_info "======================================" log_info "开始构建服务" log_info "======================================" local failed=() local succeeded=() for service_name in "${!SERVICES[@]}"; do IFS=':' read -r image_name dockerfile base_image <<< "${SERVICES[$service_name]}" if build_service "$service_name" "$image_name" "$dockerfile" "$base_image"; then succeeded+=("$service_name") else failed+=("$service_name") fi echo "" done # 汇总 log_info "======================================" log_info "构建结果" log_info "======================================" if [ ${#succeeded[@]} -gt 0 ]; then log_info "成功 (${#succeeded[@]}): ${succeeded[*]}" fi if [ ${#failed[@]} -gt 0 ]; then log_error "失败 (${#failed[@]}): ${failed[*]}" log_info "" log_info "提示: 如果失败是因为缺少预装基础镜像,请确保:" log_info " 1. 在有网环境执行: ./scripts/offline/build-base-images.sh" log_info " 2. 将生成的 base-images-with-apt.tar 传输到无网环境" log_info " 3. 在无网环境加载: docker load -i base-images-with-apt.tar" exit 1 else log_info "✓ 所有服务构建成功!" echo "" docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" | grep -E "(datamate-|deer-flow-)" || true fi } main "$@"