File size: 8,240 Bytes
fff13d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# 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