diff --git a/apps/api/src/api/tool_instances.py b/apps/api/src/api/tool_instances.py index c3c3b74..eb04078 100644 --- a/apps/api/src/api/tool_instances.py +++ b/apps/api/src/api/tool_instances.py @@ -748,7 +748,7 @@ services: write_compose_file(instance_dir, compose_content) elif tool_type.definition_type == "manifest": - # Manifest-based: generate compose from manifest definition + # Manifest-based: build image and generate compose from src.models.tool_definition_manifest import ToolDefinitionManifest manifest_def = await session.get( @@ -772,6 +772,39 @@ services: image_tag = compute_image_tag(tool_type.name, manifest) + # Build image during creation so start is fast + dockerfile = compile_dockerfile(manifest) + entrypoint = compile_entrypoint(manifest) + build_ctx = { + "Dockerfile": dockerfile, + ".headquarter/entrypoint.sh": entrypoint, + } + + returncode, stdout, stderr = await asyncio.to_thread( + build_image, + instance_dir=instance_dir, + dockerfile=dockerfile, + tag=image_tag, + build_context=build_ctx, + ) + + if returncode != 0: + logger.error( + "Failed to build image for manifest instance %s: %s", + instance_name, + stderr, + ) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Failed to build Docker image: {stderr[:500]}", + ) + + logger.info( + "Built manifest image %s for instance %s", + image_tag, + instance_name, + ) + variables = { "IMAGE_TAG": image_tag, "INSTANCE_NAME": instance_name.lower(),