cd OpenSandbox/server
uv sync --all-groups
cp opensandbox_server/examples/example.config.toml ~/.sandbox.toml
# Edit ~/.sandbox.toml as needed
uv run python -m opensandbox_server.mainExample dev config:
[server]
host = "0.0.0.0"
port = 8080
api_key = "your-secret-api-key-change-this"
[log]
level = "DEBUG"
[runtime]
type = "docker"
execd_image = "opensandbox/execd:v1.0.19"
[docker]
network_mode = "bridge"Docker daemon required for integration tests.
uv run pytest # full suite
uv run pytest tests/test_docker_service.py # single file
uv run pytest tests/k8s # k8s tests
uv run ruff check # lint
uv run pyright # type check
uv run pytest --cov=opensandbox_server --cov-report=term # with coverageLayered architecture:
- HTTP Layer — FastAPI routes, request validation, response serialization
- Middleware Layer — authentication, cross-cutting concerns
- Service Layer — business logic abstraction (
sandbox_service.py,snapshot_service.py, etc.) - Runtime Layer — Docker (
services/docker/) and Kubernetes (services/k8s/) implementations
Client → POST /sandboxes
→ Auth Middleware validates API key
→ lifecycle.create_sandbox() receives CreateSandboxRequest
→ sandbox_service.create_sandbox_async(request)
→ Returns 202 Accepted with Pending status immediately
→ Background thread provisions the sandbox
Async provisioning avoids blocking API requests during slow operations (image pull, container start). Sandbox stored in pending state first, transitions to running when ready.
In-memory timer tracking per sandbox. On timeout, sandbox is cleaned up automatically. Timers synchronized via lock for thread safety.
Bridge (recommended): isolated networks, HTTP proxy for routing.
- Endpoint:
http://{server}/route/{sandbox_id}/{port}/path
Host: sandboxes share host network, direct port access. Not recommended — no network isolation.
- Endpoint:
http://{domain}/{sandbox_id}/{port}
# Local Docker
export DOCKER_HOST="unix:///var/run/docker.sock"
# Remote Docker
export DOCKER_HOST="ssh://user@remote-host"- Config: set
[egress].image; sidecar starts only when request carriesnetworkPolicy. Requiresnetwork_mode="bridge". - Network: main container shares sidecar netns (
network_mode=container:<sidecar>); main dropsNET_ADMIN; sidecar keepsNET_ADMINfor iptables/DNS redirect. - Ports: host port bindings on sidecar; main container labels record mapped ports for endpoint resolution.
- Lifecycle: sidecar cleaned up on create failure / delete / expiration / abnormal recovery; startup removes orphaned sidecars.
- Injection:
OPENSANDBOX_EGRESS_RULESenv passesnetworkPolicyJSON; sidecar image pulled before start.