yao/sandbox/docker/build.sh
Max 83ebe49036 refactor: unify server lifecycle, migrate gRPC client, and clean up sandbox v2
Server lifecycle:
- Introduce service.Service to manage HTTP + gRPC startup/shutdown
- Fix gRPC mutex deadlock in StartServer when port is occupied
- Add GracefulStop with 5s timeout before forced Stop in grpc.go
- Pre-check HTTP and gRPC port availability in cmd/start.go
- Print gRPC server address in startup access-points block

gRPC client refactor:
- Move token manager and client from tai/grpc/ to grpc/client/
- Add backward-compatible aliases in tai/yao.go and tai/token.go
- Update cmd/run.go to import grpc/client directly (no tai dependency)

Sandbox v2 docker migration:
- Delete sandbox/v2/docker/ (moved to tai repo)
- Update sandbox/docker/build.sh hint to point to tai repo
- Clean up .gitignore entries for removed docker directory
- Temporarily disable SandboxV2Test and BenchmarkSandboxV2 in CI
  (docker images need rebuild after tai repo migration)

Tai integration:
- Add direct-mode registration API handlers in tai/api/
- Add heartbeat handler and token management wrappers
- Update tai/registry and tai/tunnel for latest protocol
- Replace yao-grpc references with tai call in docs

Made-with: Cursor
2026-03-07 17:19:19 +08:00

231 lines
7.2 KiB
Bash
Executable file

#!/bin/bash
# Build script for Yao sandbox Docker images
# Supports multi-architecture builds (amd64 and arm64)
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TOOL=${1:-claude}
PUSH=${2:-false}
REGISTRY=${REGISTRY:-"yaoapp"} # Docker Hub registry
echo "=== Building Yao Sandbox Images ==="
echo "Tool: $TOOL"
echo "Push: $PUSH"
echo "Registry: $REGISTRY"
echo "Script dir: $SCRIPT_DIR"
# Build yao-bridge for both architectures
echo ""
echo "=== Building yao-bridge (multi-arch) ==="
cd "$SCRIPT_DIR/../bridge"
echo "Building for linux/amd64..."
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o "$SCRIPT_DIR/yao-bridge-amd64" .
echo "Building for linux/arm64..."
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o "$SCRIPT_DIR/yao-bridge-arm64" .
echo "Built: yao-bridge-amd64, yao-bridge-arm64"
cd "$SCRIPT_DIR"
# Build claude-proxy for both architectures
echo ""
echo "=== Building claude-proxy (multi-arch) ==="
cd "$SCRIPT_DIR/../proxy/cmd/claude-proxy"
echo "Building for linux/amd64..."
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o "$SCRIPT_DIR/claude-proxy-amd64" .
echo "Building for linux/arm64..."
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o "$SCRIPT_DIR/claude-proxy-arm64" .
echo "Built: claude-proxy-amd64, claude-proxy-arm64"
cd "$SCRIPT_DIR"
# Check if buildx is available and set up
setup_buildx() {
echo ""
echo "=== Setting up Docker Buildx ==="
# Check if buildx is available
if ! docker buildx version > /dev/null 2>&1; then
echo "Error: Docker Buildx is not available. Please install it first."
exit 1
fi
# Create/use multi-arch builder
BUILDER_NAME="yao-multiarch"
if ! docker buildx inspect "$BUILDER_NAME" > /dev/null 2>&1; then
echo "Creating buildx builder: $BUILDER_NAME"
docker buildx create --name "$BUILDER_NAME" --use --bootstrap
else
echo "Using existing builder: $BUILDER_NAME"
docker buildx use "$BUILDER_NAME"
fi
}
# Build single-arch image (amd64 only, for Chrome which has no arm64 build)
build_amd64() {
local IMAGE_NAME=$1
local DOCKERFILE=$2
local PUSH_FLAG=$3
echo ""
echo "=== Building $IMAGE_NAME (linux/amd64 only) ==="
BUILD_ARGS="--platform linux/amd64 -t ${REGISTRY}/${IMAGE_NAME}:latest"
if [ "$PUSH_FLAG" = "true" ]; then
BUILD_ARGS="$BUILD_ARGS --push"
else
BUILD_ARGS="$BUILD_ARGS --load"
fi
docker buildx build $BUILD_ARGS -f "$DOCKERFILE" .
}
# Build multi-arch image
build_multiarch() {
local IMAGE_NAME=$1
local DOCKERFILE=$2
local PUSH_FLAG=$3
echo ""
echo "=== Building $IMAGE_NAME (linux/amd64,linux/arm64) ==="
BUILD_ARGS="--platform linux/amd64,linux/arm64 -t ${REGISTRY}/${IMAGE_NAME}:latest"
if [ "$PUSH_FLAG" = "true" ]; then
BUILD_ARGS="$BUILD_ARGS --push"
else
# Load to local Docker (only works for single platform)
echo "Note: Multi-arch build without push. Building for current platform only."
BUILD_ARGS="--load -t ${REGISTRY}/${IMAGE_NAME}:latest"
fi
docker buildx build $BUILD_ARGS -f "$DOCKERFILE" .
}
# Setup buildx for multi-arch builds
setup_buildx
# Build base image
echo ""
echo "=== Building base image ==="
build_multiarch "sandbox-base" "base/Dockerfile.base" "$PUSH"
# Build tool-specific images
case $TOOL in
claude)
echo ""
echo "=== Building Claude images ==="
build_multiarch "sandbox-claude" "claude/Dockerfile" "$PUSH"
build_multiarch "sandbox-claude-full" "claude/Dockerfile.full" "$PUSH"
;;
claude-vnc)
echo ""
echo "=== Building Claude VNC images (Browser + Desktop) ==="
build_multiarch "sandbox-claude-browser" "browser/Dockerfile" "$PUSH"
build_multiarch "sandbox-claude-desktop" "desktop/Dockerfile" "$PUSH"
;;
browser)
echo ""
echo "=== Building Claude Browser image ==="
build_multiarch "sandbox-claude-browser" "browser/Dockerfile" "$PUSH"
;;
desktop)
echo ""
echo "=== Building Claude Desktop image ==="
build_multiarch "sandbox-claude-desktop" "desktop/Dockerfile" "$PUSH"
;;
chrome)
echo ""
echo "=== Building Claude Chrome image (amd64 only) ==="
build_amd64 "sandbox-claude-chrome" "chrome/Dockerfile" "$PUSH"
;;
cursor)
echo ""
echo "=== Building Cursor images ==="
build_multiarch "sandbox-cursor" "cursor/Dockerfile" "$PUSH"
;;
all)
echo ""
echo "=== Building all images ==="
# Claude
build_multiarch "sandbox-claude" "claude/Dockerfile" "$PUSH"
build_multiarch "sandbox-claude-full" "claude/Dockerfile.full" "$PUSH"
# Claude VNC variants
build_multiarch "sandbox-claude-browser" "browser/Dockerfile" "$PUSH"
build_multiarch "sandbox-claude-desktop" "desktop/Dockerfile" "$PUSH"
# Chrome (amd64 only - Google Chrome has no arm64 Linux build)
build_amd64 "sandbox-claude-chrome" "chrome/Dockerfile" "$PUSH"
# Cursor (uncomment when ready)
# build_multiarch "sandbox-cursor" "cursor/Dockerfile" "$PUSH"
;;
v2)
echo "V2 images have moved to the tai repo: tai/docker/sandbox/build.sh"
echo "See: https://github.com/yaoapp/tai/tree/main/docker/sandbox"
exit 0
;;
*)
echo "Unknown tool: $TOOL"
echo "Usage: $0 [claude|claude-vnc|browser|desktop|chrome|cursor|v2|all] [true|false]"
echo " $0 claude # Build Claude images locally"
echo " $0 claude true # Build and push Claude images"
echo " $0 claude-vnc # Build Claude VNC images (Browser + Desktop)"
echo " $0 browser # Build Claude Browser image only"
echo " $0 desktop # Build Claude Desktop image only"
echo " $0 chrome # Build Claude Chrome image (amd64 only)"
echo " $0 v2 # Build Sandbox V2 images (base + test)"
echo " $0 all true # Build and push all images"
exit 1
;;
esac
echo ""
echo "=== Build complete ==="
echo "Images built for tool: $TOOL"
if [ "$PUSH" = "true" ]; then
echo ""
echo "Images pushed to: $REGISTRY"
echo " - ${REGISTRY}/sandbox-base:latest"
case $TOOL in
claude)
echo " - ${REGISTRY}/sandbox-claude:latest"
echo " - ${REGISTRY}/sandbox-claude-full:latest"
;;
claude-vnc)
echo " - ${REGISTRY}/sandbox-claude-browser:latest"
echo " - ${REGISTRY}/sandbox-claude-desktop:latest"
;;
browser)
echo " - ${REGISTRY}/sandbox-claude-browser:latest"
;;
desktop)
echo " - ${REGISTRY}/sandbox-claude-desktop:latest"
;;
chrome)
echo " - ${REGISTRY}/sandbox-claude-chrome:latest"
;;
all)
echo " - ${REGISTRY}/sandbox-claude:latest"
echo " - ${REGISTRY}/sandbox-claude-full:latest"
echo " - ${REGISTRY}/sandbox-claude-browser:latest"
echo " - ${REGISTRY}/sandbox-claude-desktop:latest"
echo " - ${REGISTRY}/sandbox-claude-chrome:latest"
;;
esac
fi
# Show local images
docker images | grep -E "(sandbox-base|sandbox-claude|sandbox-cursor)" | head -10 || true
# Cleanup
echo ""
echo "=== Cleanup ==="
rm -f "$SCRIPT_DIR/yao-bridge-amd64" "$SCRIPT_DIR/yao-bridge-arm64"
rm -f "$SCRIPT_DIR/claude-proxy-amd64" "$SCRIPT_DIR/claude-proxy-arm64"
echo "Removed temporary binary files"