Development Guide
This guide provides comprehensive information for developers working on OpenSandbox Server, including environment setup, architecture deep-dive, testing strategies, and contribution workflows.
📋 Table of Contents
- Development Environment Setup
- Project Structure
- Architecture Deep Dive
- Development Workflow
- Testing Guide
- Working with Docker Runtime
- Working with Kubernetes Runtime
- Code Style and Standards
- Debugging
- Performance Optimization
- Contributing
Development Environment Setup
Prerequisites
- Python 3.10+: Check version with
python --version - uv: Install from https://github.com/astral-sh/uv
- Docker: For local development and testing
- Git: Version control
- IDE: VS Code, PyCharm, or Cursor (recommended for AI assistance)
Initial Setup
Clone and Navigate
bashgit clone https://github.com/alibaba/OpenSandbox.git cd OpenSandbox/serverInstall Dependencies
bashuv syncVerify Installation
bashuv run python -c "import fastapi; print(fastapi.__version__)"Configure Development Environment
bashcp example.config.toml ~/.sandbox.tomlEdit
~/.sandbox.tomlfor local development:toml[server] host = "0.0.0.0" port = 8080 log_level = "DEBUG" api_key = "your-secret-api-key-change-this" [runtime] type = "docker" execd_image = "opensandbox/execd:v1.0.6" [docker] network_mode = "host"Run Development Server
bashuv run python -m src.main
IDE Configuration
VS Code / Cursor
Create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: FastAPI",
"type": "python",
"request": "launch",
"module": "src.main",
"justMyCode": false,
"env": {
"SANDBOX_CONFIG_PATH": "${workspaceFolder}/.sandbox.toml"
}
}
]
}PyCharm
- Open project in PyCharm
- Configure Python interpreter: Settings → Project → Python Interpreter
- Select the virtual environment created by
uv sync - Enable pytest: Settings → Tools → Python Integrated Tools → Testing → pytest
Project Structure
server/
├── src/ # Source code
│ ├── main.py # FastAPI application entry point
│ ├── config.py # Configuration management
│ ├── api/ # API layer
│ │ ├── lifecycle.py # Sandbox lifecycle routes
│ │ └── schema.py # Pydantic models
│ ├── middleware/ # Middleware components
│ │ └── auth.py # API Key authentication
│ └── services/ # Business logic layer
│ ├── sandbox_service.py # Abstract base class
│ ├── docker.py # Docker implementation
│ └── factory.py # Service factory
├── tests/ # Test suite
├── scripts/ # Utility scripts
├── pyproject.toml # Project metadata and dependencies
└── example.config.toml # Example configurationArchitecture Deep Dive
Layered Architecture
The server follows a clean layered architecture:
- HTTP Layer (FastAPI routes) - Request validation and response serialization
- Middleware Layer - Authentication and cross-cutting concerns
- Service Layer - Business logic abstraction
- Runtime Implementation Layer - Docker/Kubernetes specific code
Request Flow
Create Sandbox (Async)
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 sandboxInternal Systems
Expiration Timer System
Tracks sandbox timeouts using in-memory data structures:
_sandbox_expirations: Dict[str, datetime]- Expiration times_expiration_timers: Dict[str, Timer]- Active timer threads_expiration_lock: Lock- Thread synchronization
Async Provisioning System
Avoids blocking API requests during slow operations by:
- Storing sandboxes in pending state
- Starting background provisioning thread
- Returning 202 Accepted immediately
- Transitioning to running state when ready
Development Workflow
Feature Development
git checkout -b feature/my-feature
# Implement feature
uv run pytest
git commit -m "feat: add my feature"
git push origin feature/my-featureBug Fixes
git checkout -b fix/bug-description
# Write failing test
# Fix bug
uv run pytest
git commit -m "fix: resolve bug"Testing Guide
Running Tests
Note: A local Docker daemon is required to run the full test suite, as integration tests interact with the Docker Engine.
# All tests
uv run pytest
# Specific file
uv run pytest tests/test_docker_service.py
# With coverage
uv run pytest --cov=src --cov-report=htmlWriting Tests
Example unit test:
@patch("src.services.docker.docker")
def test_create_sandbox_validates_entrypoint(mock_docker):
service = DockerSandboxService(config=test_config())
request = CreateSandboxRequest(
image=ImageSpec(uri="python:3.11"),
timeout=120,
entrypoint=[] # Invalid
)
with pytest.raises(HTTPException):
service.create_sandbox(request)Working with Docker Runtime
Local Development
# Use local Docker
export DOCKER_HOST="unix:///var/run/docker.sock"
uv run python -m src.main
# Use remote Docker
export DOCKER_HOST="ssh://user@remote-host"
uv run python -m src.mainNetwork Modes
Host Mode (Default):
- Sandboxes share host network
- Direct port access
- Endpoint format:
http://{domain}/{sandbox_id}/{port}
Bridge Mode:
- Isolated networks
- HTTP proxy required
- Endpoint format:
http://{server}/route/{sandbox_id}/{port}/path
Egress sidecar (bridge + networkPolicy)
- Config: set
[egress].image; sidecar starts only when the request carriesnetworkPolicy. Requires Dockernetwork_mode="bridge". - Network & privileges: main container shares the sidecar netns (
network_mode=container:<sidecar>); main container explicitly dropsNET_ADMIN; sidecar keepsNET_ADMINto manage iptables / DNS transparent redirect. - Ports: host port bindings live on the sidecar; main container labels record the mapped ports for upstream endpoint resolution.
- Lifecycle: on create failure / delete / expiration / abnormal recovery, the sidecar is cleaned up; startup also removes orphaned sidecars.
- Injection:
OPENSANDBOX_EGRESS_RULESenv passes thenetworkPolicyJSON; sidecar image is pulled/ensured before start.
Working with Kubernetes Runtime
Status: Planned / Configuration Ready
Architecture will include:
- Pod management with execd init container
- Service/Ingress for networking
- CronJob or operator for expiration handling
Code Style and Standards
Follow PEP 8 with Ruff enforcement:
uv run ruff check src testsNaming Conventions
- Functions:
snake_case - Classes:
PascalCase - Constants:
UPPER_SNAKE_CASE - Private:
_leading_underscore
Type Hints
Always use type hints:
def get_sandbox(self, sandbox_id: str) -> Sandbox:
passDebugging
Enable Debug Logging
[server]
log_level = "DEBUG"Interactive Debugging
Use VS Code/Cursor breakpoints or:
breakpoint() # Python 3.7+Docker Debugging
import logging
logging.getLogger("docker").setLevel(logging.DEBUG)Performance Optimization
Profiling
python -m cProfile -o profile.stats -m src.mainOptimization Tips
- Async Operations: Use async provisioning to avoid blocking
- Connection Pooling: Reuse Docker client connections
- Caching: Cache configuration and frequently accessed data
- Resource Limits: Set appropriate container resource limits
- Monitoring: Track container creation/deletion metrics
Contributing
Pull Request Process
- Fork the repository
- Create feature branch from
main - Write tests for new functionality
- Ensure all tests pass:
uv run pytest - Run linter:
uv run ruff check - Write clear commit messages
- Submit PR with description
Code Review Guidelines
- Focus on readability and maintainability
- Ensure test coverage for new code
- Check for proper error handling
- Verify documentation updates
- Test Docker and potential Kubernetes compatibility
Commit Message Format
<type>: <description>
Types: feat, fix, docs, style, refactor, test, choreExamples:
feat: add Kubernetes runtime supportfix: resolve expiration timer memory leakdocs: update API documentation
For questions or support, please open an issue on the project repository.
This page is sourced from:
server/DEVELOPMENT.md