feat(build): 添加离线构建支持

- 新增 build-offline.sh 脚本实现无网环境构建
- 添加离线版 Dockerfiles 使用本地资源替代网络下载
- 创建 export-cache.sh 脚本在有网环境预下载依赖
- 集成 Makefile.offline.mk 提供便捷的离线构建命令
- 添加详细的离线构建文档和故障排查指南
- 实现基础镜像、BuildKit 缓存和外部资源的一键打包
This commit is contained in:
2026-02-02 21:44:44 +08:00
parent b36fdd2438
commit 9da187d2c6
9 changed files with 1085 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
#!/bin/bash
# BuildKit 离线构建脚本 - 在无网环境执行
# Usage: ./build-offline.sh [cache-dir] [version]
set -e
CACHE_DIR="${1:-./build-cache}"
VERSION="${2:-latest}"
BUILDKIT_CACHE_DIR="$CACHE_DIR/buildkit"
IMAGES_DIR="$CACHE_DIR/images"
RESOURCES_DIR="$CACHE_DIR/resources"
# 检查缓存目录
if [ ! -d "$CACHE_DIR" ]; then
echo "错误: 缓存目录 $CACHE_DIR 不存在"
echo "请先解压缓存包: tar -xzf build-cache-*.tar.gz"
exit 1
fi
# 确保 buildx 构建器存在
if ! docker buildx inspect offline-builder > /dev/null 2>&1; then
echo "创建 buildx 构建器..."
docker buildx create --name offline-builder --driver docker-container --use
else
docker buildx use offline-builder
fi
echo "======================================"
echo "1. 加载基础镜像"
echo "======================================"
if [ -f "$IMAGES_DIR/base-images.tar" ]; then
echo "$IMAGES_DIR/base-images.tar 加载基础镜像..."
docker load -i "$IMAGES_DIR/base-images.tar"
echo "✓ 基础镜像加载完成"
else
echo "警告: 基础镜像文件不存在,假设镜像已存在"
fi
echo ""
echo "======================================"
echo "2. 离线构建服务"
echo "======================================"
# 定义服务配置(与 export-cache.sh 保持一致)
SERVICES=(
"backend:datamate-backend:scripts/images/backend/Dockerfile"
"backend-python:datamate-backend-python:scripts/images/backend-python/Dockerfile"
"database:datamate-database:scripts/images/database/Dockerfile"
"frontend:datamate-frontend:scripts/images/frontend/Dockerfile"
"gateway:datamate-gateway:scripts/images/gateway/Dockerfile"
"runtime:datamate-runtime:scripts/images/runtime/Dockerfile"
"deer-flow-backend:deer-flow-backend:scripts/images/deer-flow-backend/Dockerfile"
"deer-flow-frontend:deer-flow-frontend:scripts/images/deer-flow-frontend/Dockerfile"
"mineru:datamate-mineru:scripts/images/mineru/Dockerfile"
)
# 检查是否有资源目录需要挂载
MOUNT_ARGS=""
if [ -d "$RESOURCES_DIR" ]; then
echo "检测到资源目录,将用于本地资源挂载"
MOUNT_ARGS="--build-arg RESOURCES_DIR=$RESOURCES_DIR"
fi
for service_config in "${SERVICES[@]}"; do
IFS=':' read -r service_name image_name dockerfile <<< "$service_config"
cache_file="$BUILDKIT_CACHE_DIR/$service_name-cache"
echo ""
echo "--------------------------------------"
echo "构建 [$service_name] -> $image_name:$VERSION"
echo "--------------------------------------"
if [ ! -d "$cache_file" ]; then
echo "警告: $service_name 的缓存不存在,跳过..."
continue
fi
# 使用缓存进行离线构建
# --network=none 确保不访问网络
docker buildx build \
--cache-from "type=local,src=$cache_file" \
--network=none \
-f "$dockerfile" \
-t "$image_name:$VERSION" \
--load \
. || {
echo "错误: $service_name 构建失败"
echo "尝试不使用 --network=none 重新构建..."
docker buildx build \
--cache-from "type=local,src=$cache_file" \
-f "$dockerfile" \
-t "$image_name:$VERSION" \
--load \
.
}
echo "$service_name 构建完成"
done
echo ""
echo "======================================"
echo "✓ 离线构建完成!"
echo "======================================"
echo ""
echo "构建的镜像列表:"
docker images | grep -E "(datamate-|deer-flow-)" || true