Skip to main content
When code execution doesn’t produce the expected results, isol8 provides two flags for diagnosing issues: --persist (keep the container alive for inspection) and --debug (enable internal engine logging).

Using --persist to Inspect Containers

By default, containers are cleaned up after execution. Use --persist to keep the container running so you can inspect its state:
# Run with --persist to keep the container alive
isol8 run -e "
import json
data = {'key': 'value'}
with open('/sandbox/output.json', 'w') as f:
    json.dump(data, f)
print('Done')
" --runtime python --persist
After execution, the container is still running. Find it with Docker and inspect:
# List running isol8 containers
docker ps --filter "ancestor=isol8:python"

# Exec into the container to inspect files
docker exec -it <container-id> sh
ls -la /sandbox/
cat /sandbox/output.json

# Check environment variables
docker exec <container-id> env

# Check running processes
docker exec <container-id> ps aux

Using --debug to See Engine Internals

--debug prints internal engine logs that are normally silent:
isol8 run -e "print('hello')" --runtime python --debug
This outputs [DEBUG] prefixed messages about:
  • Container pool operations (acquiring/releasing warm containers)
  • Container lifecycle (create, start, stop, remove)
  • Persist/cleanup decisions
  • Image resolution
Example debug output:
[DEBUG] Acquiring container from pool for image isol8:python
[DEBUG] Pool hit: reusing warm container abc123
[DEBUG] Executing code in container abc123
[DEBUG] Execution completed in 52ms
[DEBUG] Releasing container abc123 back to pool
[DEBUG] Container /sandbox wiped and returned to pool
hello

Combining Both Flags

Use both --persist and --debug for maximum visibility:
isol8 run -e "print('hello')" --runtime python --persist --debug
This shows you the internal decisions and keeps the container alive for inspection. The debug output will show that the container was not returned to the pool:
[DEBUG] Acquiring container from pool for image isol8:python
[DEBUG] Pool hit: reusing warm container abc123
[DEBUG] Executing code in container abc123
[DEBUG] Execution completed in 52ms
[DEBUG] Persist enabled — container abc123 NOT returned to pool
hello

Library Usage

import { DockerIsol8 } from "isol8";

const isol8 = new DockerIsol8({
  mode: "ephemeral",
  persist: true,    // Keep container after execution
  debug: true,      // Print internal logs
});

await isol8.start();

const result = await isol8.execute({
  code: 'print("debugging!")',
  runtime: "python",
});

// Container is still running — inspect it with Docker CLI
console.log("Container ID:", result.containerId);

// Don't forget to clean up manually later:
// docker rm -f <container-id>

Common Issues and Solutions

Timeout Errors

EXECUTION TIMED OUT
The code exceeded the timeout limit. Increase it:
isol8 run script.py --timeout 60000   # 60 seconds
For debugging, use --persist to see how far the code got:
isol8 run script.py --timeout 60000 --persist
# Then inspect /sandbox/ in the container

Out of Memory

Killed
The container hit the memory limit and was OOM-killed. Increase memory:
isol8 run script.py --memory 2g

No Space Left on Device

OSError: [Errno 28] No space left on device
The /sandbox or /tmp tmpfs is full. Increase the size:
isol8 run script.py --sandbox-size 1g --tmp-size 512m

Package Installation Failures

Operation not permitted
Native packages (numpy, pandas) need execution permission on the install directory. isol8 installs to /sandbox which has exec, but the sandbox may be too small:
isol8 run -e "import numpy" --runtime python --install numpy --sandbox-size 1g

Runtime Mismatch in Persistent Mode

Error: Cannot switch runtime from "python" to "node"
Persistent containers are locked to one runtime. Create separate instances:
const pythonEngine = new DockerIsol8({ mode: "persistent" });
const nodeEngine = new DockerIsol8({ mode: "persistent" });

Debugging Network Issues

For filtered mode connectivity problems, use --debug to see proxy logs and test with curl:
# Test what's reachable
isol8 run -e "
import urllib.request
try:
    resp = urllib.request.urlopen('https://api.github.com')
    print(f'OK: {resp.status}')
except Exception as e:
    print(f'Blocked: {e}')
" --runtime python --net filtered --allow "^api\.github\.com$" --debug

Cleanup After Debugging

After using --persist, clean up leftover containers:
# Remove all isol8 containers
isol8 cleanup

# Or force without confirmation
isol8 cleanup --force
Programmatically:
const result = await DockerIsol8.cleanup();
console.log(`Removed ${result.removed} containers`);