fix(build): reuse multi-tenant ComfyUI image instead of rebuilding every run

- skip docker build when boosapi-comfyui:multi-tenant already exists;
  --rebuild-image opts back into a fresh build
- fall back to `docker load` from docker/boosapi-comfyui-multi-tenant-*.tar
  when the image is absent but the saved tar is present
- gate the whole block on `docker info` so a client-only host doesn't hang
  on build when the daemon is unreachable
This commit is contained in:
boos
2026-05-20 19:40:39 +08:00
parent cf696c01a5
commit 423912277b
+66
View File
@@ -12,6 +12,7 @@ RELEASE=0
FRONTEND_ONLY=0
BACKEND_ONLY=0
NO_RUN=0
REBUILD_IMAGE=0
usage() {
cat <<'EOF'
@@ -22,6 +23,7 @@ usage() {
--frontend-only 只构建前端
--backend-only 只构建后端
--no-run 构建后不启动服务
--rebuild-image 强制重新构建多租户 ComfyUI 镜像(默认:已存在则跳过)
-h, --help 显示帮助
EOF
}
@@ -32,6 +34,7 @@ while [ $# -gt 0 ]; do
--frontend-only) FRONTEND_ONLY=1 ;;
--backend-only) BACKEND_ONLY=1 ;;
--no-run) NO_RUN=1 ;;
--rebuild-image) REBUILD_IMAGE=1 ;;
-h|--help) usage; exit 0 ;;
*) echo "未知参数: $1" >&2; usage >&2; exit 1 ;;
esac
@@ -44,6 +47,25 @@ log() { echo "[$(date '+%H:%M:%S')] $*"; }
ok() { echo "[$(date '+%H:%M:%S')] ✓ $*"; }
fail() { echo "[$(date '+%H:%M:%S')] ✗ $*" >&2; exit 1; }
# ── 同步 ComfyUI 子模块 + 应用本地补丁 ─────────────────────────────────────────
# comfy_source/ 是 vanilla ComfyUI 的 git 子模块,本地补丁存放在
# comfy_patches/overlay/,由 comfy_patches/apply.sh 覆盖到子模块上。
# Dockerfile 把整个 comfy_source/ 复制进镜像,所以这一步必须在 docker
# build 之前完成,否则镜像里只会有 vanilla 代码。
if [ -f "$ROOT_DIR/.gitmodules" ] && [ -d "$ROOT_DIR/.git" ]; then
if [ ! -f "$ROOT_DIR/comfy_source/main.py" ]; then
log "初始化 ComfyUI 子模块..."
git submodule update --init --recursive
ok "子模块已初始化"
fi
if [ -d "$ROOT_DIR/comfy_patches/overlay" ]; then
log "应用 ComfyUI 本地补丁 (comfy_patches/overlay → comfy_source/)..."
"$ROOT_DIR/comfy_patches/apply.sh"
ok "本地补丁已应用"
fi
fi
# ── 构建前端 ──────────────────────────────────────────────────────────────────
if [ "$BACKEND_ONLY" -eq 0 ]; then
@@ -63,6 +85,12 @@ if [ "$FRONTEND_ONLY" -eq 0 ]; then
fail "未找到 cargo,请先安装 Rust 工具链"
fi
# 提示一次:如果链接器走默认 ld 而 mold 不在 PATH,给出一条性能建议。
# mold 安装后还需在 .cargo/config.toml 取消 `linker = "clang"` 那段注释。
if ! command -v mold >/dev/null 2>&1; then
log "提示: 安装 mold 后取消 .cargo/config.toml 中的相应注释,链接将快 3-5x"
fi
if [ "$RELEASE" -eq 1 ]; then
log "构建后端 (cargo build --release)..."
cargo build --release
@@ -76,6 +104,44 @@ if [ "$FRONTEND_ONLY" -eq 0 ]; then
fi
fi
# ── 构建多租户 ComfyUI 镜像 ───────────────────────────────────────────────────
# 多租户 ComfyUI 镜像 (boosapi-comfyui:multi-tenant) 由 ComfyUIPool 在每次
# 拉新用户容器时使用。镜像很重(~700MB),不必每次 ./build-and-run.sh 都
# 重打。优先级:
# 1. 已存在同名镜像 → 跳过(--rebuild-image 强制重建)
# 2. 有 docker/boosapi-comfyui-multi-tenant-*.tar 备份 → docker load
# 3. 都没有 → docker build
#
# `docker info` 用来确认 daemon 真的在跑,避免在只装了 client 的环境里
# 卡 build。失败的话整段跳过,API 仍可走 legacy 单实例路径。
if [ "$FRONTEND_ONLY" -eq 0 ]; then
if command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
IMAGE="boosapi-comfyui:multi-tenant"
SAVED_TAR="$(ls "$ROOT_DIR"/docker/boosapi-comfyui-multi-tenant-*.tar 2>/dev/null | head -1 || true)"
DOCKERFILE="$ROOT_DIR/docker/Dockerfile.comfyui.multi-tenant"
if [ "$REBUILD_IMAGE" -eq 0 ] && docker image inspect "$IMAGE" >/dev/null 2>&1; then
log "镜像 $IMAGE 已存在,跳过构建(--rebuild-image 强制重建)"
elif [ "$REBUILD_IMAGE" -eq 0 ] && [ -n "$SAVED_TAR" ]; then
log "从 $SAVED_TAR 加载 $IMAGE..."
docker load -i "$SAVED_TAR"
ok "镜像已加载 → $IMAGE"
elif [ -f "$DOCKERFILE" ]; then
log "构建多租户 ComfyUI 镜像 ($IMAGE)..."
docker build \
-f "$DOCKERFILE" \
-t "$IMAGE" \
"$ROOT_DIR"
ok "ComfyUI 多租户镜像构建完成 → $IMAGE"
else
log "未找到 $DOCKERFILE,跳过镜像构建"
fi
else
log "docker 不可用(未安装或 daemon 未运行),跳过多租户 ComfyUI 镜像准备"
fi
fi
# ── 启动服务 ──────────────────────────────────────────────────────────────────
if [ "$NO_RUN" -eq 1 ] || [ "$FRONTEND_ONLY" -eq 1 ]; then