Skip to main content
info

This documentation is automatically synchronized from the claude-hub repository. Last updated: 2025-06-01

Container Pooling Implementation - Lessons Learned

Original Problem

User requested container pooling to improve performance by keeping containers ready instead of creating them on-demand for each request.

What We Tried

1. Container Persistence Issues

  • Problem: Containers were exiting immediately after creation
  • Root Cause: Original claudecode:latest image was designed for single-command execution with --rm flag
  • Solution: Changed container creation to use tail -f /dev/null to keep containers alive
  • Result: ✅ Containers now stay running

2. Execution Model Mismatch

  • Problem: Pooled containers needed different execution approach than on-demand containers
  • Original Clean Execution: Single Docker run command with full entrypoint setup
  • Pooled Execution Attempt: Complex multi-step process:
    1. Clone repository into running container
    2. Set up environment
    3. Execute Claude Code directly
  • Issues:
    • Broke the clean single-command execution model
    • Required complex command file handling
    • Made error handling more complex
    • Lost the simplicity of the original design

3. Architecture Conflicts

  • Original Design: Stateless containers that handle everything from scratch
  • Pooled Design: Stateful containers that need workspace management
  • Conflict: The execution logic became significantly more complex

Key Insights

  1. Container Persistence: Using --entrypoint="/bin/bash" -c "echo 'ready'; exec tail -f /dev/null" keeps containers alive
  2. Execution Complexity: Pooled containers require fundamentally different execution logic
  3. Clean Design: The original single Docker run command was elegant and reliable
  4. Workspace Management: Pooled containers need careful workspace cleanup between uses

Instead of complex pooled execution, consider:

  1. Container Pre-warming: Keep containers running but use the same execution model
  2. Simpler Pool Usage:
    • Use pooled containers for faster startup
    • But execute using the same clean entrypoint approach
    • Pass the same environment variables and let the entrypoint handle setup
  3. Hybrid Approach:
    • Keep the clean docker run execution model
    • But reuse container instances by removing --rm flag
    • Clean up containers after use rather than during creation

Next Steps

  1. Revert to original clean execution approach
  2. Implement simpler pooling that doesn't change execution complexity
  3. Focus on container reuse rather than execution model changes

Code Locations

  • Container pool service: src/services/containerPoolService.ts
  • Execution logic: src/services/claudeService.ts:170-210
  • Container creation: Modified Docker command in pool service

Performance Gains Observed

  • ✅ Container creation time reduced (containers stay alive)
  • ❌ Execution complexity increased significantly
  • ❌ Error handling became more complex
  • ❌ Lost single-command simplicity