Skip to content

Latest commit

 

History

History
95 lines (69 loc) · 3.04 KB

File metadata and controls

95 lines (69 loc) · 3.04 KB

Development Guide

Setup

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.main

Example 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"

Testing

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 coverage

Architecture

Layered architecture:

  1. HTTP Layer — FastAPI routes, request validation, response serialization
  2. Middleware Layer — authentication, cross-cutting concerns
  3. Service Layer — business logic abstraction (sandbox_service.py, snapshot_service.py, etc.)
  4. Runtime Layer — Docker (services/docker/) and Kubernetes (services/k8s/) implementations

Request Flow: Create Sandbox

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.

Expiration System

In-memory timer tracking per sandbox. On timeout, sandbox is cleaned up automatically. Timers synchronized via lock for thread safety.

Docker Runtime

Network Modes

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"

Egress Sidecar (bridge + networkPolicy)

  • Config: set [egress].image; sidecar starts only when request carries networkPolicy. Requires network_mode="bridge".
  • Network: main container shares sidecar netns (network_mode=container:<sidecar>); main drops NET_ADMIN; sidecar keeps NET_ADMIN for 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_RULES env passes networkPolicy JSON; sidecar image pulled before start.