FastAPI control plane for OpenSandbox that manages sandbox lifecycle on Docker (ready) and Kubernetes (planned) runtimes.
Project description
OpenSandbox Server
A production-grade, FastAPI-based service for managing the lifecycle of containerized sandboxes. It acts as the control plane to create, run, monitor, and dispose isolated execution environments across container platforms.
Features
Core capabilities
- Lifecycle APIs: Standardized REST interfaces for create, start, pause, resume, delete
- Pluggable runtimes:
- Docker: Production-ready
- Kubernetes: Production-ready (see
../kubernetes/README.mdfor deployment)
- Lifecycle cleanup modes: Configurable TTL with renewal, or manual cleanup with explicit delete
- Access control: API Key authentication (
OPEN-SANDBOX-API-KEY); can be disabled for local/dev - Networking modes:
- Host: shared host network, performance first
- Bridge: isolated network with built-in HTTP routing
- Resource quotas: CPU/memory limits with Kubernetes-style specs
- Observability: Unified status with transition tracking
- Registry support: Public and private images
Extended capabilities
- Async provisioning: Background creation to reduce latency
- Timer restoration: Expiration timers restored after restart
- Env/metadata injection: Per-sandbox environment and metadata
- Port resolution: Dynamic endpoint generation
- Structured errors: Standard error codes and messages
Metadata keys under the reserved prefix opensandbox.io/ are system-managed
and cannot be supplied by users.
Requirements
- Python: 3.10 or higher
- Package Manager: uv (recommended) or pip
- Runtime Backend:
- Docker Engine 20.10+ (for Docker runtime)
- Kubernetes 1.21.1+ (for Kubernetes runtime)
- Operating System: Linux, macOS, or Windows with WSL2
Quick Start
Installation
Install from PyPI. For local development, clone the repo and run uv sync in server/.
uv pip install opensandbox-server
Configuration
The server reads a TOML file. Default path: ~/.sandbox.toml. Override with SANDBOX_CONFIG_PATH or opensandbox-server --config /path/to/sandbox.toml.
- Generate a starter file (see
opensandbox-server -hfor all flags):
opensandbox-server init-config ~/.sandbox.toml --example docker
# Kubernetes: --example k8s (deploy the operator / CRDs per ../kubernetes/ first)
# Locales: docker-zh | k8s-zh | omit --example for a schema-only skeleton | add --force to overwrite
-
Edit the file for your environment. Full reference: configuration.md (all keys, defaults, validation, env vars).
Topics covered there include: Docker
network_mode/host_ip(e.g. server in Docker Compose),[egress]when clients sendnetworkPolicy,[ingress],[secure_runtime], Kubernetesworkload_provider/batchsandbox_template_file,[agent_sandbox], TTL caps,[renew_intent].
Also useful: Secure container runtime · Manual cleanup / optional fields · Egress component · docker-compose.example.yaml · Experimental features
Run the server
opensandbox-server
# opensandbox-server --config /path/to/sandbox.toml
Listens on server.host / server.port from your TOML (defaults in configuration.md).
Health check (adjust host/port if you changed them):
curl http://127.0.0.1:8080/health
# → {"status": "healthy"}
If startup, Docker/Kubernetes, or connectivity fails, see Troubleshooting.
API documentation
Once the server is running, interactive API documentation is available:
- Swagger UI: http://localhost:8080/docs
- ReDoc: http://localhost:8080/redoc
API authentication
Authentication is enforced only when server.api_key is set. If the value is empty or missing, the middleware skips API Key checks (intended for local/dev). For production, always set a non-empty server.api_key and send it via the OPEN-SANDBOX-API-KEY header.
All API endpoints (except /health, /docs, /redoc) require authentication via the OPEN-SANDBOX-API-KEY header when authentication is enabled:
curl -H "OPEN-SANDBOX-API-KEY: your-secret-api-key" http://localhost:8080/v1/sandboxes
Example usage
Create a Sandbox
curl -X POST "http://localhost:8080/v1/sandboxes" \
-H "OPEN-SANDBOX-API-KEY: your-secret-api-key" \
-H "Content-Type: application/json" \
-d '{
"image": {
"uri": "python:3.11-slim"
},
"entrypoint": [
"python",
"-m",
"http.server",
"8000"
],
"timeout": 3600,
"resourceLimits": {
"cpu": "500m",
"memory": "512Mi"
},
"env": {
"PYTHONUNBUFFERED": "1"
},
"metadata": {
"team": "backend",
"project": "api-testing"
}
}'
Response:
{
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"status": {
"state": "Pending",
"reason": "CONTAINER_STARTING",
"message": "Sandbox container is starting.",
"lastTransitionAt": "2024-01-15T10:30:00Z"
},
"metadata": {
"team": "backend",
"project": "api-testing"
},
"expiresAt": "2024-01-15T11:30:00Z",
"createdAt": "2024-01-15T10:30:00Z",
"entrypoint": ["python", "-m", "http.server", "8000"]
}
Other lifecycle calls (same OPEN-SANDBOX-API-KEY header): GET /v1/sandboxes/{id}, GET /v1/sandboxes/{id}/endpoints/{port} (append ?use_server_proxy=true when needed), POST .../renew-expiration, DELETE /v1/sandboxes/{id}. Full request/response shapes: Swagger UI above or OpenAPI under specs/.
Architecture
Component responsibilities
- API Layer (
opensandbox_server/api/): HTTP request handling, validation, and response formatting - Service Layer (
opensandbox_server/services/): Business logic for sandbox lifecycle operations - Middleware (
opensandbox_server/middleware/): Cross-cutting concerns (authentication, logging) - Configuration (
opensandbox_server/config.py): Centralized configuration management - Runtime Implementations: Platform-specific sandbox orchestration
Sandbox lifecycle states
create()
│
▼
┌─────────┐
│ Pending │────────────────────┐
└────┬────┘ │
│ │
│ (provisioning) │
▼ │
┌─────────┐ pause() │
│ Running │───────────────┐ │
└────┬────┘ │ │
│ resume() │ │
│ ┌────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────┐ │
├─│ Paused │ │
│ └────────┘ │
│ │
│ delete() or expire() │
▼ │
┌──────────┐ │
│ Stopping │ │
└────┬─────┘ │
│ │
├────────────────┬────────┘
│ │
▼ ▼
┌────────────┐ ┌────────┐
│ Terminated │ │ Failed │
└────────────┘ └────────┘
Configuration reference
Single source of truth for TOML: configuration.md (includes SANDBOX_CONFIG_PATH, DOCKER_HOST, PENDING_FAILURE_TTL).
Experimental features
Optional 🧪 experimental behavior; off by default in example.config.toml (and mirrored copies under opensandbox_server/examples/). See release notes before production.
Auto-renew on access
Extends sandbox TTL when traffic is observed (lifecycle proxy and/or ingress + optional Redis queue). Design and operations: OSEP-0009. TOML keys ([renew_intent], including nested redis.*): see configuration.md and example.config.toml.
Per-sandbox: on create, set extensions["access.renew.extend.seconds"] (string integer 300–86400). Clients using the server proxy: request endpoints with use_server_proxy=true (REST) or SDK ConnectionConfig(..., use_server_proxy=True) — details in OSEP-0009.
Development
Code quality
Run linter:
uv run ruff check
Auto-fix issues:
uv run ruff check --fix
Format code:
uv run ruff format
Testing
Run all tests:
uv run pytest
Run with coverage:
uv run pytest --cov=opensandbox_server --cov-report=html
Run specific test:
uv run pytest tests/test_docker_service.py::test_create_sandbox_requires_entrypoint
License
This project is licensed under the terms specified in the LICENSE file in the repository root.
Contributing
Contributions are welcome. Follow the repository CONTRIBUTING.md (Conventional Commits, PR expectations). Typical flow:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for new functionality
- Ensure all tests pass (
uv run pytest) - Run linting (
uv run ruff check) - Commit with clear messages
- Push to your fork
- Open a Pull Request
Support
- Troubleshooting: TROUBLESHOOTING.md — common failures (config, Docker, networking, K8s) and fixes
- Development: DEVELOPMENT.md
- Issues: Report defects via GitHub Issues
- Discussions: GitHub Discussions for Q&A and ideas
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opensandbox_server-0.1.11.tar.gz.
File metadata
- Download URL: opensandbox_server-0.1.11.tar.gz
- Upload date:
- Size: 122.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7e95b8a6c9586b4cc0e99e2d94d1d357ea4343e1b5e1a6bf254539b5a4d054ee
|
|
| MD5 |
8b022d933fd5c2f4b3f0d221c0865192
|
|
| BLAKE2b-256 |
5a10161ce09801ef449a08718d4ab65aeefa637a22fe7469128af75e938eb59a
|
File details
Details for the file opensandbox_server-0.1.11-py3-none-any.whl.
File metadata
- Download URL: opensandbox_server-0.1.11-py3-none-any.whl
- Upload date:
- Size: 182.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92c13c3dedcf8a71bd73d705d4bdd81b0fbb3d14eb1ea6cba8e263a12d87fe55
|
|
| MD5 |
720f9a1231ab465683791f1cf2e42059
|
|
| BLAKE2b-256 |
13543b5373c99ba43bd4188510155498130340f9042d5f7229d0d7c680a7e693
|