manim-mcp / BLAXEL_SANDBOX_SETUP.md
bhaveshgoel07's picture
Deploy code fixes (clean history)
fff13d1
# Blaxel Sandbox Setup for Manim + FFmpeg
This guide walks you through creating and deploying a custom Blaxel sandbox with Manim and FFmpeg pre-installed for rendering animations in the cloud.
## Overview
Instead of installing Manim and FFmpeg at runtime (which is slow and unreliable), we create a custom Docker image with all dependencies pre-installed. This image is then deployed to Blaxel as a sandbox template that can be instantiated on-demand for rendering.
## Why Custom Image?
- **Faster**: No installation overhead at runtime
- **Reliable**: Pre-tested environment with all dependencies
- **FFmpeg Support**: System-level dependencies properly configured
- **LaTeX Support**: Optional but recommended for mathematical animations
## Prerequisites
1. **Docker** installed locally (for testing)
2. **Blaxel CLI** installed: `npm install -g @blaxel/cli`
3. **Blaxel Account** with API key from [blaxel.ai](https://blaxel.ai)
4. **Environment Variables** set:
```bash
export BLAXEL_API_KEY="your_api_key_here"
export BL_WORKSPACE="your_workspace_id" # Optional
```
## Step 1: Build and Test Locally
Before deploying to Blaxel, test the image locally:
```bash
# Build the Docker image
make -f Makefile.sandbox build
# Run the container locally
make -f Makefile.sandbox run
# Test the sandbox API (in another terminal)
make -f Makefile.sandbox test
# View logs
make -f Makefile.sandbox logs
# Stop the container
make -f Makefile.sandbox stop
```
### Manual Testing
You can also test manually:
```bash
# 1. Check Manim installation
curl -X POST http://localhost:8080/process \
-H "Content-Type: application/json" \
-d '{
"command": "python3 -c \"import manim; print(manim.__version__)\"",
"waitForCompletion": true
}'
# 2. Check FFmpeg installation
curl -X POST http://localhost:8080/process \
-H "Content-Type: application/json" \
-d '{
"command": "ffmpeg -version",
"waitForCompletion": true
}'
# 3. Test a simple Manim render
curl -X POST http://localhost:8080/process \
-H "Content-Type: application/json" \
-d '{
"command": "python3 -c \"from manim import *; print(\\\"Manim import successful\\\")\"",
"waitForCompletion": true
}'
```
## Step 2: Deploy to Blaxel
Once local testing is successful, deploy to Blaxel:
```bash
# Login to Blaxel (if not already logged in)
bl login
# Deploy the sandbox template
make -f Makefile.sandbox deploy
# Or manually:
bl deploy
```
This will:
1. Build your Docker image
2. Push it to Blaxel's registry
3. Create a sandbox template named based on your project
## Step 3: Get the Image ID
After deployment, retrieve your custom image ID:
```bash
# List your sandboxes
bl get sandboxes
# Get specific sandbox details with image ID
bl get sandbox manim-sandbox -ojson | jq -r '.[0].spec.runtime.image'
```
The output will look something like:
```
blaxel/your-workspace/manim-sandbox:latest
```
**Save this image ID** - you'll need it in the next step.
## Step 4: Update Renderer Code
Update the renderer to use your custom image instead of the generic one.
Open `mcp_servers/renderer.py` and find the line around line 440:
```python
sandbox = await SandboxInstance.create(
{
"name": f"manim-render-{sanitized_scene_name}",
"image": "blaxel/py-app:latest", # Change this line
"memory": 4096,
}
)
```
Replace `"blaxel/py-app:latest"` with your custom image ID:
```python
sandbox = await SandboxInstance.create(
{
"name": f"manim-render-{sanitized_scene_name}",
"image": "blaxel/your-workspace/manim-sandbox:latest", # Your custom image
"memory": 4096,
}
)
```
**Better approach**: Use an environment variable:
```python
import os
MANIM_SANDBOX_IMAGE = os.getenv(
"MANIM_SANDBOX_IMAGE",
"blaxel/your-workspace/manim-sandbox:latest"
)
sandbox = await SandboxInstance.create(
{
"name": f"manim-render-{sanitized_scene_name}",
"image": MANIM_SANDBOX_IMAGE,
"memory": 4096,
}
)
```
Then add to your `.env`:
```bash
MANIM_SANDBOX_IMAGE=blaxel/your-workspace/manim-sandbox:latest
```
## Step 5: Test End-to-End
Now test the complete pipeline:
```bash
# Run your animation generation
python main_new.py
```
Or if using Gradio:
```bash
python app.py
```
The system should now:
1. Create a sandbox using your custom image
2. Upload the Manim code
3. Execute the render command (Manim and FFmpeg already available)
4. Download the rendered video
## Configuration Options
### Memory Allocation
For complex animations, you may need more memory:
```python
sandbox = await SandboxInstance.create(
{
"name": f"manim-render-{sanitized_scene_name}",
"image": MANIM_SANDBOX_IMAGE,
"memory": 8192, # Increased from 4096
}
)
```
### Timeout Settings
Adjust timeouts for longer renders:
```python
render_result = await sandbox.process.exec({
"name": "render-manim",
"command": cmd,
"wait_for_completion": True,
"timeout": 600000, # 10 minutes (in milliseconds)
})
```
### Custom LaTeX Packages
If you need additional LaTeX packages, update the Dockerfile:
```dockerfile
RUN apt-get install -y \
texlive-full \ # Install full LaTeX distribution
&& rm -rf /var/lib/apt/lists/*
```
Then rebuild and redeploy:
```bash
make -f Makefile.sandbox rebuild
make -f Makefile.sandbox deploy
```
## Troubleshooting
### Issue: "Sandbox creation failed"
**Solution**: Check your API key and workspace:
```bash
echo $BLAXEL_API_KEY
echo $BL_WORKSPACE
```
Re-login if needed:
```bash
bl login
```
### Issue: "Image not found"
**Solution**: Verify the image was deployed:
```bash
bl get sandboxes
```
If not listed, redeploy:
```bash
bl deploy
```
### Issue: "Manim not found in sandbox"
**Solution**: Verify the image has Manim:
```bash
# Connect to a running sandbox
bl connect sandbox your-sandbox-name
# Inside the sandbox, test:
python3 -c "import manim; print(manim.__version__)"
```
### Issue: "FFmpeg not found"
**Solution**: Similar to above, verify FFmpeg:
```bash
bl connect sandbox your-sandbox-name
ffmpeg -version
```
### Issue: "Render timeout"
**Solutions**:
1. Increase memory allocation (try 8192 MB)
2. Increase timeout value
3. Simplify the animation
4. Use lower quality settings
### Issue: "Build fails locally"
**Solution**: Check Docker logs:
```bash
docker logs manim-sandbox-test
```
Common issues:
- Missing entrypoint.sh file (copy it first)
- Permissions on entrypoint.sh (should be executable)
- Docker daemon not running
## Cost Optimization
To minimize costs:
1. **Use TTL policies**: Sandboxes auto-delete when idle
```python
sandbox = await SandboxInstance.create({
"name": f"manim-render-{sanitized_scene_name}",
"image": MANIM_SANDBOX_IMAGE,
"memory": 4096,
"lifecycle": {
"expiration_policies": [
{"type": "ttl-idle", "value": "5m", "action": "delete"}
]
}
})
```
2. **Delete after use**: Explicitly delete sandboxes when done
```python
try:
# Render animation
pass
finally:
await SandboxInstance.delete(sandbox.metadata.name)
```
3. **Reuse sandboxes**: For batch processing, reuse the same sandbox
## Advanced: Multiple Sandbox Versions
You can maintain multiple versions:
```bash
# Tag with version
docker build -f Dockerfile.sandbox -t manim-sandbox:v1.0 .
# Deploy specific version
bl deploy --tag v1.0
```
Then specify in code:
```python
"image": "blaxel/your-workspace/manim-sandbox:v1.0"
```
## Next Steps
1. βœ… Build and test locally
2. βœ… Deploy to Blaxel
3. βœ… Update renderer code with image ID
4. βœ… Test end-to-end rendering
5. βœ… Configure cost optimization
6. πŸŽ‰ Start generating animations!
## Resources
- [Blaxel Sandboxes Documentation](https://docs.blaxel.ai/sandboxes)
- [Blaxel CLI Reference](https://docs.blaxel.ai/cli)
- [Manim Documentation](https://docs.manim.community/)
- [FFmpeg Documentation](https://ffmpeg.org/documentation.html)
## Support
If you encounter issues:
1. Check the Blaxel dashboard for sandbox logs
2. Review the deployment logs: `bl logs`
3. Join Blaxel Discord/Support channels
4. Check GitHub issues for similar problems