Produkty
Sandboxes
Izolowane środowiska (microVM) do uruchamiania kodu przez agentów AI: exec, pliki, kernel Pythona, podgląd portów, SDK, MCP i AI Gateway.
Sandboxes (Panel → projekt → Sandboxes) to izolowane środowiska uruchamiane na żądanie, w których agent AI lub Twoja aplikacja może bezpiecznie wykonać dowolny kod. Każdy sandbox to osobna maszyna: domyślnie microVM (Kata Containers + Cloud Hypervisor, własne jądro i izolacja KVM), opcjonalnie gVisor (tańszy, szybszy start, jądro w przestrzeni użytkownika). Sandboxy działają wyłącznie na dedykowanym serwerze workerów, bez dostępu do baz danych.
Szybki start
curl -X POST https://host.ulewicz.space/api/v1/projects/<ref>/sandboxes \
-H "Authorization: Bearer $HOSTBASE_TOKEN" -H "Content-Type: application/json" \
-d '{"template":"python-3.12"}'
# -> { "id": "sbx...", "state": "running", "timings": { "total_ms": 40, "from_pool": true }, ... }
curl -X POST .../sandboxes/<id>/exec -H "Authorization: Bearer $HOSTBASE_TOKEN" \
-d '{"cmd":"python3 -c \"print(1+1)\""}'
# -> { "exit_code": 0, "stdout": "2\n", "stderr": "" }
curl -X DELETE .../sandboxes/<id> -H "Authorization: Bearer $HOSTBASE_TOKEN"
Szablony
| Id | Nazwa | Zawartość |
|---|---|---|
python-3.12 | Python 3.12 (data science) | numpy, pandas, matplotlib, scipy, scikit-learn, seaborn; Jupyter-like kernel with PNG charts and HTML tables |
node-22 | Node.js 22 | Node.js 22 LTS, npm, git, build tools |
bun | Bun 1 | Bun runtime, package manager, test runner |
ubuntu | Ubuntu 24.04 (base) | Ubuntu 24.04 + Python 3, pip, git, curl, jq, build-essential |
playwright-chromium | Playwright + Chromium | Playwright with Chromium/Firefox/WebKit (headless browser automation) |
Limity i plany
Domyślnie: 1 vCPU, 1024 MB RAM, 5 GB dysku (/workspace), wyłączenie po 5 min bezczynności (idle_timeout_s, 30 s – 24 h; wywołania API, ruch na adresie podglądu i obciążenie CPU ≥ 10% jednego vCPU odnawiają licznik) i po maks. 1 h życia (lifetime_s, do 24 h). Dysk /workspace to osobny obraz ext4 o stałym rozmiarze — zapis ponad limit kończy się błędem „No space left”.
| Plan | maks. vCPU | maks. RAM | maks. dysk | maks. życie | równolegle | w cenie (godz. vCPU / godz. GB) |
|---|---|---|---|---|---|---|
| free | 1 | 1024 MB | 2 GB | 1 h | 2 | 5 / 10 |
| pro | 2 | 4096 MB | 20 GB | 24 h | 10 | 100 / 200 |
| team | 4 | 8192 MB | 50 GB | 24 h | 40 | 500 / 1000 |
Exec i strumieniowanie
POST …/exec przyjmuje cmd (tekst uruchamiany w bash -c albo tablica argumentów), cwd, env, timeout_s (domyślnie 60) i stdin. Z "stream": true odpowiedź to strumień SSE zdarzeń {"type":"stdout"|"stderr"|"exit",…}. Z "background": true proces startuje w tle (wyjście w pliku logu), np. serwer HTTP. Zmienne środowiskowe ustawione przy tworzeniu są dostępne w każdym wywołaniu. Interaktywny terminal (xterm.js) jest w panelu; w API: terminal + strumień SSE + input.
Pliki
Ścieżki względne liczą się od /workspace. files/list, files/content (surowe bajty, GET/PUT/DELETE), files/mkdir oraz files/archive (tar — hurtowe wgrywanie i pobieranie katalogu). Limit pojedynczego pliku: 256 MB.
Uruchamianie kodu (kernel)
POST …/run-code z {"code": "…", "language": "python"} działa jak komórka notebooka: kernel Pythona (szablony python-3.12 i ubuntu) zachowuje stan między wywołaniami o tym samym context_id. Odpowiedź zawiera listę results: stdout, stderr, wartość ostatniego wyrażenia (text/plain), tabele text/html (pandas), wykresy matplotlib jako image/png (base64) oraz obiekt error z tracebackiem. Dla javascript (Node/Bun) i bash każdy przebieg jest bezstanowy.
Adresy podglądu portów
Dowolny port sandboxa jest dostępny pod https://<id>-<port>.sbx.workers-waw1.host.ulewicz.space (certyfikat TLS, WebSockety obsługiwane). Domyślnie podgląd jest publiczny (adres zawiera losowy identyfikator); z "preview": "private" wymagany jest token (nagłówek x-hostbase-sandbox-token lub ?hb_token=, zwrócony przy tworzeniu). Odpowiedzi mają X-Robots-Tag: noindex. Dostęp do adresu liczy się jako aktywność (odnawia timeout bezczynności).
Pauza i wznowienie
pause w trybie freeze zamraża maszynę w pamięci (wznowienie w dziesiątkach ms, procesy przeżywają; rozliczana jest tylko połowa stawki za RAM, bez CPU). Tryb stop zatrzymuje maszynę i zwalnia RAM, a zachowuje dysk /workspace (wznowienie to zimny start ok. 2 s, procesy nie przeżywają). Wstrzymany sandbox wygasa po 24 h.
Polityka ruchu wychodzącego
open— internet dostępny (domyślnie);allowlist— tylko wskazane nazwy hostów lub adresy IP/CIDR (nazwy są rozwiązywane i odświeżane co 5 min; DNS do 1.1.1.1 / 8.8.8.8 jest dozwolony);none— brak ruchu wychodzącego.
Niezależnie od trybu zablokowane są zawsze: sieci prywatne (RFC1918, w tym serwery baz danych), usługa metadanych chmury, sieci innych sandboxów, port 25 oraz porty typowe dla koparek kryptowalut (stratum).
Metryki, logi, zużycie
metrics zwraca próbki co 10 s (CPU, RAM, sieć, procesy) i zajętość dysku; logs — zdarzenia cyklu życia i log kernela; usage — zużycie miesięczne projektu i organizacji względem limitu planu.
Rozliczenie
Płacisz za zarezerwowane zasoby w czasie, gdy sandbox działa: vCPU-sekundy i GB-sekundy RAM. W planie: Free 5 godz. vCPU i 10 godz. GB (twardy limit), Pro 100 / 200, Team 500 / 1000. Powyżej limitu: 0,25 zł netto za godzinę vCPU i 0,04 zł za godzinę GB. Pozycje widać w Koszty i na fakturze.
Model bezpieczeństwa
- Izolacja: microVM Kata + Cloud Hypervisor — oddzielne jądro gościa i granica sprzętowa (KVM); gVisor jako opcja. Kod nie widzi hosta ani innych sandboxów.
- Sieć: osobny mostek i podsieć na sandbox; bez dostępu do sieci prywatnych, metadanych chmury, baz danych i innych sandboxów.
- Zasoby: sztywne limity CPU, RAM, PID-ów i dysku, wymuszone wyłączenie po bezczynności i po maks. czasie życia.
- Nadużycia: wykrywamy stale wysycone CPU, procesy koparek i próby połączeń stratum. Sandbox z koparką jest wyłączany, a właściciel dostaje powiadomienie.
- Sekrety: sandbox nie dostaje kluczy projektu — przekazujesz tylko zmienne
env, które sam wskażesz.
Zakresy tokenów
sandboxes:read (lista, metryki, logi, zużycie) i sandboxes:write (tworzenie, exec, pliki, terminal, zamykanie); sandboxes:* daje oba. W rolach projektu zapis mają owner, admin i developer; readonly tylko odczyt.
Management API
GET|POST /api/v1/projects/{ref}/sandboxes (?all=1 includes recently ended)
GET /api/v1/projects/{ref}/sandboxes/templates
GET /api/v1/projects/{ref}/sandboxes/usage
GET|DELETE /api/v1/projects/{ref}/sandboxes/{id}
POST /api/v1/projects/{ref}/sandboxes/{id}/pause { mode: "freeze" | "stop" }
POST /api/v1/projects/{ref}/sandboxes/{id}/resume
POST /api/v1/projects/{ref}/sandboxes/{id}/timeout { idle_timeout_s, lifetime_s }
POST /api/v1/projects/{ref}/sandboxes/{id}/egress { mode: "open"|"allowlist"|"none", hosts }
POST /api/v1/projects/{ref}/sandboxes/{id}/ports { port }
POST /api/v1/projects/{ref}/sandboxes/{id}/exec { cmd, cwd, env, timeout_s, stdin, stream, background }
POST /api/v1/projects/{ref}/sandboxes/{id}/run-code { code, language, context_id, timeout_s }
GET /api/v1/projects/{ref}/sandboxes/{id}/files/list?path=
GET|PUT|DELETE /api/v1/projects/{ref}/sandboxes/{id}/files/content?path=
POST /api/v1/projects/{ref}/sandboxes/{id}/files/mkdir?path=
GET|PUT /api/v1/projects/{ref}/sandboxes/{id}/files/archive?path= (tar)
GET /api/v1/projects/{ref}/sandboxes/{id}/metrics
GET /api/v1/projects/{ref}/sandboxes/{id}/logs
POST /api/v1/projects/{ref}/sandboxes/{id}/terminal { cols, rows } -> { session_id }
GET /api/v1/projects/{ref}/sandboxes/{id}/terminal/{sid}/stream (SSE, base64 chunks)
POST /api/v1/projects/{ref}/sandboxes/{id}/terminal/{sid}/input { data, base64 }
POST /api/v1/projects/{ref}/sandboxes/{id}/terminal/{sid}/resize { cols, rows }
DELETE /api/v1/projects/{ref}/sandboxes/{id}/terminal/{sid}
SDK TypeScript
import { Sandbox } from "@hostbase/sandbox";
const sbx = await Sandbox.create({ apiKey: process.env.HOSTBASE_TOKEN!, project: "<ref>", template: "python-3.12", timeoutS: 600 });
const r = await sbx.exec("ls -la /workspace"); // { exitCode, stdout, stderr }
await sbx.files.write("/workspace/hello.py", "print('hi')");
const text = await sbx.files.read("/workspace/hello.py");
const run = await sbx.runCode("import numpy as np; np.arange(5).sum()");
await sbx.close();
Szkielet SDK dla Pythona znajdziesz w repozytorium (sdk/sandbox-python).
MCP
Narzędzia dla Claude Code, Cursora i innych agentów: create_sandbox, sandbox_exec, sandbox_run_code, sandbox_write_file, sandbox_read_file, list_sandboxes i close_sandbox. Wymagają zakresu sandboxes:write (lista: sandboxes:read).
AI Gateway: code_interpreter
W żądaniu do /api/ai/v1/chat/completions dodaj "hostbase_tools": ["code_interpreter"]. Bramka udostępnia modelowi narzędzie wykonujące Pythona w sandboxie projektu (kernel ze stanem, wykresy zwracane jako obrazy) i prowadzi pętlę narzędzi do 4 rund; sandbox jest zamykany po zakończeniu odpowiedzi.
Wydajność startu
Dla każdego szablonu trzymamy małą pulę rozgrzanych microVM o domyślnym rozmiarze (1 vCPU / 1 GB / 5 GB). Utworzenie sandboxa o domyślnych parametrach przejmuje gotową maszynę (rzędu dziesiątek ms); niestandardowe parametry lub pusta pula oznaczają zimny start (ok. 2 s). Pole timings w odpowiedzi pokazuje, co się stało.
Pomiary na host-workers-waw1 (D4as_v5, 4 vCPU / 16 GB)
| Krok | Mediana / zakres |
|---|---|
| Utworzenie z puli (domyślny rozmiar, microVM) | 12-29 ms |
| Pierwsze polecenie po utworzeniu | 130-200 ms |
| Utworzenie, zimny start microVM | 1.9-2.1 s / 1.8-1.9 s / 1.6 s / 1.6 s / 1.6 s |
| Utworzenie, zimny start gVisor | 0.65 s / 0.60 s |
| Management API POST /sandboxes end-to-end (z puli) | ~260 ms |
| Pauza (freeze) / wznowienie | 41-46 ms / 37-48 ms |
| Pauza (stop) / wznowienie (start VM) | 0.54 s / 1.4 s |
| run-code Python, pierwsze wywołanie (import pandas + matplotlib) / kolejne | 2.5 s / 0.12 s |
| Zamknięcie (usunięcie VM, dysku, sieci) | 0.63-0.68 s |
Pula rozgrzanych maszyn: 3 x python-3.12, 2 x ubuntu, 2 x node-22 (uzupełniana w tle, ok. 2 s na sztukę). Zimny start obejmuje utworzenie mostu sieciowego, obrazu dysku ext4, start maszyny Kata + Cloud Hypervisor i oczekiwanie na agenta gościa.