feat(scripts): 添加 APT 缓存预装功能解决离线构建问题

- 新增 APT 缓存目录和相关构建脚本 export-cache.sh
- 添加 build-base-images.sh 脚本用于构建预装 APT 包的基础镜像
- 增加 build-offline-final.sh 最终版离线构建脚本
- 更新 Makefile.offline.mk 添加新的离线构建目标
- 扩展 README.md 文档详细说明 APT 缓存问题解决方案
- 为多个服务添加使用预装基础镜像的离线 Dockerfile
- 修改打包脚本包含 APT 缓存到最终压缩包中
This commit is contained in:
2026-02-03 13:16:12 +08:00
parent 31629ab50b
commit da5b18e423
10 changed files with 794 additions and 31 deletions

View File

@@ -0,0 +1,181 @@
#!/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 "$@"