Architecture
DockerRuntime Class
Implemented inesprit/runtime/docker_runtime.py, the DockerRuntime manages sandbox lifecycle:
Initialization
- Docker Desktop installed and running
- Docker daemon accessible via Docker socket
- Sufficient Docker resources (2+ GB RAM, 10+ GB disk)
Configuration
Environment variables:| Variable | Default | Description |
|---|---|---|
ESPRIT_IMAGE | (required) | Docker image name (e.g., esprit/sandbox:latest) |
ESPRIT_SANDBOX_TIMEOUT | 60 | Docker API timeout in seconds |
ESPRIT_SANDBOX_EXECUTION_TIMEOUT | 120 | Tool execution timeout in seconds |
ESPRIT_DOCKER_PLATFORM | (auto) | Platform override (e.g., linux/amd64, linux/arm64) |
Container Lifecycle
1. Container Creation
Method:_create_container() (lines 137-197)
Creation Process
Creation Process
- Remove existing container with same name if present
- Find available port for tool server (random port 1024-65535)
- Generate auth token (32-byte URL-safe random token)
- Pull image if not cached locally
- Create container with configuration:
- Wait for tool server to become healthy (max 30 attempts)
NET_ADMIN: Required for network manipulation (proxy setup)NET_RAW: Required for raw socket access (port scanning)
2. Tool Server Health Check
Method:_wait_for_tool_server() (lines 89-135)
- Initial 5-second delay for container startup
- Poll every 0.5-5 seconds (exponential backoff)
- Max 30 attempts (configurable)
- Monitors container status (fails fast if container exits)
- Container exits during initialization → includes container logs in error
- Container removed during initialization → “Container was removed”
- Timeout after 30 attempts → includes last 50 lines of container logs
3. Container Reuse
Method:_get_or_create_container() (lines 199-243)
Containers are reused across agents in the same scan:
- Faster agent initialization
- Shared workspace state
- Resource efficiency
4. Local Source Copying
Method:_copy_local_directory_to_container() (lines 275-312)
When scanning local code, files are copied to container’s /workspace:
Copy Process
Copy Process
- Create tar archive of local directory
- Exclude directories:
node_modules,.git,__pycache__.venv,venv,.env,envdist,build,.next,.nuxttarget,vendor,.bundle
- Upload tar to container via Docker API
- Set permissions:
chown -R pentester:pentester /workspace - Track copied state to avoid duplicate copying
5. Sandbox Info Response
Method:create_sandbox() returns SandboxInfo:
6. Container Cleanup
Method:destroy_sandbox() (lines 406-415)
- On normal scan completion
- On CLI process exit (via
cleanup()method) - Cleanup uses background subprocess to avoid blocking
Workspace Diffs
Method:get_workspace_diffs() (lines 386-404)
Retrieves list of file edits made during scan:
command: “edit”, “write”, “delete”path: File path relative to workspaceold_str: Original content (for edits)new_str: New content (for edits)content: Full content (for writes)
Network Configuration
Port Mapping
- Container port 48081 → Random host port (e.g., 54321)
- Tool server binds to
0.0.0.0:48081inside container - Esprit CLI connects to
127.0.0.1:<random_port>
Host Access
- Useful for scanning
localhostservices host.docker.internalresolves to host IP
Docker Host Resolution
Method:_resolve_docker_host() (lines 376-384)
Container Image
The Esprit sandbox image (ESPRIT_IMAGE) includes:
Base System
- Ubuntu 22.04 LTS
- Python 3.11+
- Node.js 20+ (for browser automation)
Security Tools
nmap,nikto,sqlmapffuf,gobuster,dirbwhatweb,wpscan- Custom scanning scripts
Tool Server
- FastAPI application
- Esprit tools package
- Playwright browsers (Chromium)
- mitmproxy for HTTP interception
User Configuration
- Non-root user:
pentester(UID 1000) - Home directory:
/home/pentester - Workspace:
/workspace(writable)
Error Handling
Docker Not Available
Docker Not Available
- Docker daemon not running
- Docker socket not accessible
- Connection timeout
Image Pull Failures
Image Pull Failures
Retry logic with exponential backoff:
- Max 3 attempts
- Delays: 1s, 2s, 4s
- Verifies image metadata after pull
Container Start Failures
Container Start Failures
- Container logs (last 50 lines)
- Exit code if container exited
- Detailed error message
Tool Server Timeout
Tool Server Timeout
Performance Optimization
Container Reuse
- Single container per scan (shared across agents)
- Avoids repeated image pulls
- Maintains tool state (browser sessions, terminals)
Async Operations
- HTTP requests use
httpx.AsyncClient - Non-blocking tool execution
- Parallel agent support
Resource Management
- Tool server timeout prevents runaway processes
- Container memory limits (configurable via Docker)
- Automatic cleanup on exit
Troubleshooting
Container won't start
Container won't start
- Check Docker daemon:
docker ps - Check image exists:
docker images | grep esprit - Check port conflicts:
lsof -i :<port> - Check Docker resources: Increase memory/CPU in Docker Desktop
- View container logs:
docker logs esprit-scan-<scan_id>
Tool server not responding
Tool server not responding
- Check health endpoint:
curl http://127.0.0.1:<port>/health - Check container status:
docker ps -a - Check firewall/network settings
- Increase timeout:
ESPRIT_SANDBOX_TIMEOUT=120
Permission errors in workspace
Permission errors in workspace
- Ensure files are owned by pentester user
- Check container:
docker exec -it esprit-scan-<id> ls -la /workspace - Fix permissions: Container automatically runs
chownon upload
Next Steps
Cloud Runtime
Alternative to local Docker setup
Tools
Learn about available tools in sandbox