Jak samodzielnie hostować sandboxd na własnym VPS
Dowiedz się, jak wdrożyć sandboxd na serwerze VPS z Dockerem. Instrukcja konfiguracji Traefik v3, zarządzania kontenerami, kluczami modeli oraz czyszczenia nieaktywnych sesji.
Czym jest sandboxd i co zyskujesz, uruchamiając go samodzielnie
Do samodzielnego hostowania sandboxd wymagany jest jeden serwer z systemem Linux, Dockerem oraz nazwa domenowa. Po wysłaniu promptu agent programistyczny buduje rzeczywistą aplikację w izolowanym kontenerze, a aplikacja ta zostaje udostępniona pod własnym adresem URL podglądu. Narzędzia typu prompt-to-app to najpopularniejsza kategoria oprogramowania w 2026 roku, a sandboxd jest rozwiązaniem, które uruchomisz na własnym VPS, na licencji MIT, z wygenerowanym kodem zapisanym na Twoim dysku.
Projekt jest celowo minimalistyczny. Płaszczyzna sterowania w Go zarządza Dockerem, Traefik v3 kieruje ruch dla każdej nazwy hosta podglądu, SQLite przechowuje stan, a każda aplikacja działa wewnątrz pojedynczego kontenera. Brak tu Kubernetes oraz oddzielnego serwera bazy danych, dzięki czemu całość może działać na maszynie z 2 vCPU.
Cały model opiera się na czterech obiektach. App to trwały projekt, przechowujący swoją nazwę, metadane git oraz sekrety. Sandbox to kontener Docker, w którym działa aplikacja; jedna aplikacja wskazuje w danej chwili na jeden sandbox. Workspace to pliki aplikacji, które znajdują się na hoście i są zachowywane po zamknięciu kontenera. Task to pojedynczy prompt przekazany agentowi wewnątrz sandboxa. Zatrzymanie sandboxa zwalnia pamięć, ale zachowuje pliki. Usunięcie sandboxa powoduje likwidację kontenera, a aplikacja może uruchomić nowy.
Czym sandboxd różni się od Dify i OpenHands?
Te trzy narzędzia są często mylone, ponieważ każde z nich uruchamia LLM (duży model językowy) na serwerze, jednak ich wynik końcowy jest odmienny. Dify służy do budowania aplikacji LLM: interfejsów czatu, potoków wyszukiwania (retrieval pipelines) oraz przepływów pracy, które wywołują model przy każdym użyciu. Model stanowi integralną część gotowego produktu. OpenHands pracuje na istniejącym repozytorium: wskazuje się mu kod, a narzędzie odczytuje pliki, wykonuje polecenia i proponuje zmiany. sandboxd zaczyna od zera. Tworzy szkielet projektu na podstawie szablonu, buduje go w odizolowanym kontenerze i udostępnia adres URL do podglądu. Wynikiem jest standardowa aplikacja React lub FastAPI, która do działania nie wymaga modelu.
Wybór zależy od oczekiwanego rezultatu. sandboxd służy do tworzenia projektu na podstawie opisu i zachowania kodu po zakończeniu pracy. Pozostałe dwa narzędzia są przeznaczone do pracy z istniejącym repozytorium lub produktem opartym na modelu.
Kolejną różnicą jest wiek projektu, co należy wziąć pod uwagę przed budowaniem na nim poważnych rozwiązań.
The data behind this chart
[
{
"tool": "sandboxd",
"github_stars": "875",
"forks": "50"
},
{
"tool": "OpenHands",
"github_stars": "83,091",
"forks": "10,711"
},
{
"tool": "Dify",
"github_stars": "151,320",
"forks": "23,886"
}
]sandboxd posiada 875 gwiazdek, w porównaniu do 83,091 dla OpenHands oraz 151,320 dla Dify. Repozytorium utworzono 3 czerwca 2026 roku, więc w sierpniu 2026 roku projekt ma dwa miesiące. OpenHands istnieje od marca 2024 roku, a Dify od kwietnia 2023 roku. Wersja v0.1.0 została wydana 6 czerwca 2026 roku, a v0.3.6 pojawiła się 1 sierpnia 2026 roku. Projekt określa się jako beta i zaznacza, że wydania 0.x mogą wprowadzać zmiany niekompatybilne wstecz. Liczby te należy traktować jako wskaźnik ryzyka zależności, a nie ocenę jakości: dwumiesięczny projekt miał jedynie dwa miesiące na wykrycie błędów przez społeczność.
Czego serwer potrzebuje i co ulega awarii przy niedoborach
Projekt zakłada, że 2 vCPU i 4 GB pamięci RAM wystarczą do uruchomienia. Jest to poprawne dla płaszczyzny sterowania (control plane) oraz jednego małego środowiska izolowanego (sandbox), jednak niewystarczające dla dwóch osób pracujących jednocześnie. Należy zaplanować przydział pamięci w częściach. Traefik oraz płaszczyzna sterowania w języku Go zajmują niewiele miejsca. Każde działające środowisko izolowane przechowuje pełny zestaw narzędzi Node lub Python, a szczytowe zapotrzebowanie występuje podczas npm install, po którym następuje budowanie produkcyjne. Należy zaplanować 8 GB dla serwera, który ma utrzymywać kilka aplikacji, a swap traktować jako zabezpieczenie, a nie jako zasób wydajnościowy, ponieważ budowanie korzystające ze swapu trwa minuty zamiast sekund.
W przypadku wyczerpania pamięci występują dwie różne awarie, które nie wykazują podobieństw. Wewnątrz środowiska izolowanego kontener osiąga twardy limit --memory ustawiony przez sandboxd, co powoduje, że jądro systemu kończy proces o największym zużyciu pamięci. W rezultacie proces budowania kończy się bez użytecznego komunikatu ze strony agenta. docker ps -a wykazuje kod wyjścia 137 dla tego kontenera, a docker inspect zgłasza dla niego "OOMKilled": true. Budowanie w Node, które kończy się w ten sposób, często wyświetla wcześniej JavaScript heap out of memory.
Druga awaria dotyczy hosta. sandboxd uruchamia mechanizm monitorowania ciśnienia (pressure reaper), który zatrzymuje środowiska izolowane, gdy pamięć hosta jest na wyczerpaniu. Na małej maszynie środowisko izolowane może zniknąć w trakcie przeglądania podglądu. Pliki pozostają bezpieczne, a kolejne żądanie pod adres URL podglądu wybudza je, jednak zadanie, które było uruchomione w momencie zatrzymania kontenera, nie zostanie wznowione.
Dysk stanowi mniej oczywisty problem. Każda aplikacja przechowuje własny obszar roboczy na hoście, a projekt JavaScript zawiera drzewo node_modules o rozmiarze setek megabajtów. Dziesięć aplikacji to kilka gigabajtów samych zależności, nie licząc obrazów. Należy zacząć od 40 GB i monitorować zużycie:
docker system df
sudo du -sh /var/lib/sandboxed/workspacesDomyślny katalog danych to /var/lib/sandboxed, zapisywany z dodatkowym e. Wpisanie /var/lib/sandboxd prowadzi do pustego katalogu i pięciu minut dezorientacji.
Instalacja przypiętej wersji sandboxd
Na serwerze musi być zainstalowany Docker Engine z wtyczką Compose oraz git. Artykuł Instalacja Docker na VPS opisuje ten etap.
docker compose version
git --versionOba polecenia muszą zwrócić wersję. Błąd docker: 'compose' is not a docker command oznacza obecność starego, samodzielnego pliku binarnego docker-compose, podczas gdy instalator wymaga wtyczki w wersji v2.
Instalator to skrypt powłoki pobierany z sieci, dlatego należy go przejrzeć przed uruchomieniem i przypiąć wersję.
curl -fsSL https://raw.githubusercontent.com/tastyeffectco/sandboxd/v0.3.6/install.sh -o install-sandboxd.sh
less install-sandboxd.sh
SANDBOXD_REF=v0.3.6 bash install-sandboxd.shSANDBOXD_REF to referencja git, którą instalator pobiera do $HOME/.sandboxd/src; domyślnie jest to main. Pozostawienie tej zmiennej nieustawionej oznacza instalację wersji, która została scalona danego dnia, co ma znaczenie w projekcie, który tylko w lipcu 2026 roku wydał sześć wersji. Należy przypiąć wersję, a następnie aktualizować ją celowo po zapoznaniu się z listą zmian.
Skrypt klonuje kod źródłowy, buduje obrazy, uruchamia stos za pomocą docker compose up -d i na końcu wyświetla adres URL konsoli oraz token API. Token należy zapisać w bezpiecznym miejscu. Jest to poświadczenie dla API, które zarządza Dockerem z uprawnieniami root.
curl http://127.0.0.1:9090/healthzPolecenie to wyświetla ok, gdy płaszczyzna sterowania jest gotowa. Jeśli wynik jest pusty, stos nie został uruchomiony: należy wykonać docker compose ps w katalogu ~/.sandboxd/src, aby sprawdzić, która usługa nie działa, a następnie docker compose logs sandboxd, aby poznać przyczynę.
Uzyskiwanie dostępu do konsoli na zdalnym serwerze
Konsola jest udostępniana przez Traefik na porcie HTTP_PORT, który domyślnie ma wartość 80, pod nazwą hosta http://console.localhost. Traefik kieruje ruch na podstawie nazwy hosta, więc wpisanie adresu IP serwera w przeglądarce nie pasuje do żadnej reguły i zwraca błąd 404. Do czasu skonfigurowania właściwej domeny należy przekierować port i zachować nazwę hosta:
ssh -L 8080:127.0.0.1:80 you@your-vpsNastępnie otwórz http://console.localhost:8080 na swoim laptopie. W systemach Linux i macOS każda nazwa kończąca się na .localhost jest rozwiązywana na 127.0.0.1, dzięki czemu żądanie trafia do tunelu z poprawnym nagłówkiem Host. Przy pierwszej wizycie ustaw hasło do konsoli.
Przypisanie modelu do agenta
W obrazie bazowym dostarczane są dwa agenty programistyczne: OpenCode oraz Claude Code. SANDBOXD_DEFAULT_AGENT decyduje, który z nich wykona zadanie, jeśli nie wskazano konkretnego agenta; domyślnie wybierany jest opencode. Bez podłączonego klucza zadania są uruchamiane na darmowych modelach OpenCode Zen, dzięki czemu pierwsze kompilacje są bezpłatne, co pozwala przetestować cały cykl pracy przed poniesieniem jakichkolwiek kosztów.
Podłącz własny klucz, jeśli potrzebujesz wydajniejszego modelu. Klucze trafiają do płaszczyzny sterowania (control plane), nigdy do środowiska izolowanego (sandbox): są przechowywane w formie zaszyfrowanej w katalogu danych i przekazywane przez proxy uwierzytelniające, więc ani agent, ani tworzony przez niego kod nie mają do nich dostępu.
export API=http://127.0.0.1:9090
export SANDBOXD_TOKEN=sk_... # printed by the installer
export AUTH="Authorization: Bearer $SANDBOXD_TOKEN"
curl -s -XPOST $API/v1/agents/claude-code/api-key -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"api_key":"sk-ant-..."}'Konsola oferuje te same funkcje w sekcji Settings, AI Agents, w tym proces OAuth, jeśli zamiast klucza API chcesz użyć subskrypcji Claude. Domyślny model dla każdego agenta można skonfigurować w tym samym panelu, a pojedyncze zadanie może nadpisać to ustawienie.
Budowa małej aplikacji od podstaw
Utwórz aplikację, uruchom jej piaskownicę (sandbox), a następnie wyślij zapytanie. Identyfikatory są zwracane w formacie JSON, a przewodnik szybkiego startu wyodrębnia je za pomocą sed, więc nie musisz mieć zainstalowanego jq.
APP=$(curl -s -XPOST $API/v1/apps -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"name":"todo","runtime_preset":"react-vite"}' \
| sed -E 's/.*"id":"([^"]+)".*/\1/')
SB=$(curl -s -XPOST $API/v1/apps/$APP/sandbox -H "$AUTH" \
-H 'content-type: application/json' -d '{"ports":[3000]}' \
| sed -E 's/.*"id":"([^"]+)".*/\1/')
echo "app=$APP sandbox=$SB"Obie zmienne muszą zawierać identyfikator. Pusta wartość $SB oznacza, że piaskownica nigdy się nie uruchomiła; najczęstszą przyczyną jest trwający proces budowania obrazu bazowego lub brak pamięci operacyjnej na hoście. Wartość 401 zamiast identyfikatora oznacza nieprawidłowy token uwierzytelniający (bearer token).
curl -s -XPOST $API/v1/sandboxes/$SB/tasks -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"prompt":"Add a todo list with a text input, an add button, and a delete button on each row. Keep the list in localStorage.","agent":"opencode"}'Odpowiedź zawiera identyfikator zadania. GET /v1/sandboxes/$SB/tasks/<task id> zwraca jego wynik, a ścieżka /events dla tego samego zadania to aktywny strumień SSE (server sent events) pokazujący działania agenta. Konsola wyświetla ten sam strumień w formie czatu.
Aplikacja jest dostępna pod adresem http://s-<sandbox id>-3000.preview.localhost, gdzie 3000 to port, o który wnioskowano. Jeśli piaskownica była w stanie uśpienia, pierwsze żądanie trafia do mechanizmu catch-all w Traefik, sandboxd uruchamia kontener, oczekuje na odpowiedź portu i wyświetla krótką stronę informacyjną, która odświeża się automatycznie po załadowaniu aplikacji. Jeśli podgląd nie wychodzi poza tę stronę, oznacza to, że proces wewnątrz kontenera nie nasłuchuje na porcie zadeklarowanym w sandbox.yaml aplikacji.
Udostępnianie podglądów w domenie z HTTPS
Każde środowisko testowe otrzymuje własną nazwę hosta, co pozwala na obsługę wszystkich za pomocą jednego rekordu DNS typu wildcard. Skieruj *.preview.yourdomain.com na adres IP serwera za pomocą rekordu A. Następnie skonfiguruj zmienne podglądu w .env w pliku ~/.sandboxd/src:
PREVIEW_DOMAIN=yourdomain.com
PREVIEW_ENTRYPOINT=websecure
PREVIEW_TLS=true
SANDBOXD_API_AUTH_DISABLED=falseTraefik wymaga odpowiedniej konfiguracji: włącz punkt wejścia websecure w traefik/traefik.yml i dodaj resolver certyfikatów. Użyj wyzwania DNS-01, ponieważ jeden certyfikat typu wildcard obejmuje wszystkie nazwy hostów podglądu. W przypadku HTTP-01 każde nowe środowisko wymagałoby osobnego wystawienia certyfikatu, co przy intensywnej pracy szybko doprowadzi do przekroczenia limitów Let’s Encrypt. Artykuł Certyfikaty wildcard poprzez wyzwanie DNS-01 opisuje konfigurację po stronie DNS.
cd ~/.sandboxd/src
docker compose up -dAdresy URL podglądu przyjmują postać https://s-<id>-3000.preview.yourdomain.com. Otwórz porty 80 oraz 443 na zaporze sieciowej i pozostaw port 9090 zamknięty dla ruchu z zewnątrz: zobacz podstawowe reguły zapory ufw. Pamiętaj, że każda osoba, która odgadnie nazwę hosta podglądu, może załadować aplikację, dlatego traktuj podglądy jako publicznie dostępne.
Gdzie trafia wygenerowany kod i czy można go wyeksportować?
Na hoście, w katalogu danych. Każdy obszar roboczy to zwykły katalog w /var/lib/sandboxed/workspaces/<id>/, montowany jako bind mount w kontenerze, a pliki aplikacji znajdują się w /home/sandbox/workspace/app wewnątrz piaskownicy. Stan płaszczyzny sterowania to pojedynczy plik SQLite w state/sandboxd.db, a zaszyfrowane poświadczenia agenta znajdują się w agent-auth/. Nic nie jest ukryte w warstwach kontenera, więc kopia zapasowa to po prostu kopia katalogu oraz wspomnianego pliku bazy danych. kopie zapasowe restic na VPS obsługują oba te elementy.
sudo ls /var/lib/sandboxed/workspaces
sudo du -sh /var/lib/sandboxed/workspaces/*Eksport do Git jest wbudowany, a nie dodany jako zewnętrzny moduł. API udostępnia status i diff do odczytu, a następnie operacje commit i push:
curl -s $API/v1/apps/$APP/git/status -H "$AUTH"
curl -s -XPOST $API/v1/apps/$APP/git/commit -H "$AUTH" \
-H 'content-type: application/json' \
-d '{"message":"todo list, first pass"}'
curl -s -XPOST $API/v1/apps/$APP/git/push -H "$AUTH" \
-H 'content-type: application/json' -d '{"branch":"main"}'Prywatne repozytorium zdalne wymaga osobistego tokena dostępu (personal access token), ustawianego jednorazowo w konsoli w sekcji Settings, Git credentials. Jest on przechowywany w formie zaszyfrowanej i pozostaje poza piaskownicą, dzięki czemu agent nie może go odczytać ani wykonać operacji push bez wiedzy użytkownika. Należy często wykonywać push. Do tego momentu katalog obszaru roboczego jest jedyną kopią kodu, a DELETE /v1/apps/<id> usuwa go bez możliwości przywrócenia.
Ile tokenów modelu kosztuje kompilacja?
sandboxd nie monitoruje wydatków, dlatego wiążące dane znajdują się w konsoli dostawcy usług. Darmowe modele OpenCode Zen nie generują kosztów, jednak są wolniejsze i mniej wydajne niż modele płatne, co w przypadku projektów wykraczających poza proste aplikacje testowe skutkuje większą liczbą cykli korekty.
Struktura rachunku wynika ze sposobu działania pętli agenta. Każda tura przesyła ponownie wymagany kontekst, więc koszt zależy od liczby tur, a nie od liczby aplikacji. Pojedynczy, trafny prompt jest tani. Piętnaście rund poleceń typu „popraw odstępy” w projekcie zawierającym pięćdziesiąt plików generuje wysokie koszty, ponieważ zawartość plików jest przesyłana za każdym razem. Tokeny wejściowe i wyjściowe są wyceniane inaczej, a artykuł ile kosztuje agent programistyczny na sesję przedstawia realistyczny zakres cenowy. Przed uruchomieniem pętli działającej bez nadzoru należy ustawić twardy limit wydatków w panelu dostawcy.
Czyszczenie nieaktywnych środowisk izolowanych (sandboxes)
Mechanizm idle reaper zatrzymuje każde środowisko izolowane, które pozostawało bezczynne przez czas przekraczający SANDBOXD_IDLE_THRESHOLD_SECONDS; domyślnie jest to 2100 sekund, czyli 35 minut. Powoduje to zwolnienie pamięci RAM przy zachowaniu plików, a kolejne żądanie wysłane na adres URL podglądu automatycznie uruchamia kontener. Warto zmniejszyć tę wartość na serwerach o ograniczonej ilości zasobów, ponieważ 35 minut bezczynności kontenerów oznacza 35 minut zajętej pamięci, której nie można wykorzystać w inny sposób.
Zatrzymanie nie jest równoznaczne z usunięciem, co prowadzi do stopniowego zapełniania dysku. Zatrzymane środowisko izolowane nadal posiada swój obszar roboczy oraz kontener. Usunięcie środowiska przy zachowaniu aplikacji wykonuje operację DELETE na środowisku, co powoduje usunięcie kontenera oraz obszaru roboczego. Usunięcie aplikacji powoduje trwałe usunięcie wszystkich powiązanych danych.
curl -s -XPOST $API/v1/sandboxes/$SB/stop -H "$AUTH" # frees RAM, keeps files
curl -s -XDELETE $API/v1/sandboxes/$SB -H "$AUTH" # container and workspace gone
curl -s -XDELETE $API/v1/apps/$APP -H "$AUTH" # app and everything under itPo kilku tygodniach eksperymentów polecenie docker system df wykaże więcej miejsca możliwego do odzyskania z obrazów, niż można by oczekiwać, ponieważ każda aplikacja, która pobrała własny łańcuch narzędzi, pozostawiła po sobie warstwy. Polecenie docker image prune usuwa nieużywane warstwy (dangling images). Należy najpierw sprawdzić GET /v1/apps, ponieważ obraz, do którego odwołuje się uśpione środowisko izolowane, nie jest traktowany jako zbędny.
Czym jest, a czym nie jest granica kontenera
Każda piaskownica działa jako użytkownik bez uprawnień z systemem plików root w trybie tylko do odczytu, z odrzuconymi wszystkimi możliwościami Linux capabilities, ustawionym no-new-privileges, limitem pamięci oraz ograniczeniem liczby procesów. Projekt otwarcie informuje o ograniczeniach tego rozwiązania: kontener Linux współdzielący jądro stanowi silną barierę izolacji, lecz słabą barierę bezpieczeństwa. Błąd w jądrze oznacza przejęcie hosta.
Dwa fakty wymagają podjęcia działań. Ruch wychodzący z piaskownicy jest otwarty w samodzielnie hostowanej kompilacji, więc wygenerowany kod może łączyć się z Internetem, siecią lokalną oraz punktami końcowymi metadanych chmury. Podsystem wyjściowy nftables istnieje w kodzie źródłowym, ale jest wyłączony w przenośnej kompilacji Docker Compose, co oznacza, że ograniczenia muszą zostać nałożone przez firewall hosta. Ponadto API płaszczyzny sterowania (control plane) posiada w praktyce uprawnienia root hosta, ponieważ zarządza gniazdem Docker socket. Domyślnie wiąże się ono z 127.0.0.1:9090, SANDBOXD_API_AUTH_DISABLED musi pozostać false i nigdy nie powinno być wystawiane do Internetu.
Jeśli planujesz umożliwić innym osobom wysyłanie zapytań do swojego środowiska, ten model zabezpieczeń jest niewystarczający. Projekt wskazuje na gVisor z SANDBOXD_RUNTIME=runsc, który umieszcza jądro w przestrzeni użytkownika (userspace) między piaskownicą a hostem, co wiąże się ze spadkiem wydajności operacji systemowych od 1,7 do 4 razy. Silniejszym rozwiązaniem jest przypisanie jednej maszyny na użytkownika, co stanowi ten sam argument, co w przypadku uruchamiania agentów programistycznych w tymczasowej maszynie wirtualnej.
Czy warto budować projekt na bazie dwumiesięcznego oprogramowania?
W przypadku osobistego serwera budującego – tak, przy zachowaniu oczywistych środków ostrożności: przypięciu wersji SANDBOXD_REF, wykonaniu kopii zapasowej /var/lib/sandboxed oraz wypchnięciu każdej istotnej aplikacji do zdalnego repozytorium git. W przypadku wszystkiego, z czego korzysta klient, należy poczekać na wersję 1.0 lub uwzględnić w budżecie koszty awarii, ponieważ autorzy otwarcie deklarują, że wersje 0.x mogą ulec zmianie w dowolnym momencie. Autorzy oferują również zarządzaną instalację w cenie 79 dolarów miesięcznie (stan na sierpień 2026), co warto wziąć pod uwagę przy ocenie, czy projekt ma uzasadnienie dla dalszego istnienia.
Ryzyko jest akceptowalne ze względu na wynik końcowy. sandboxd tworzy zwykłą aplikację w zwykłym repozytorium git, więc w przypadku porzucenia projektu zachowujesz kod, tracąc jedynie wrapper. Jest to znacznie lepsza sytuacja niż w przypadku hostowanego kreatora, który przejmuje kontrolę nad Twoim projektem. Szersze spojrzenie na to, co warto hostować samodzielnie w tym roku, znajduje się w sekcji co warto hostować samodzielnie w 2026.
FAQ
Jakie są minimalne wymagania sprzętowe serwera dla sandboxd?
Projekt wymaga 2 vCPU oraz 4 GB pamięci RAM do uruchomienia płaszczyzny sterowania, Traefik oraz jednego małego środowiska sandbox. Należy zapewnić 8 GB pamięci RAM oraz 40 GB miejsca na dysku, aby uruchomić jednocześnie kilka aplikacji, ponieważ każdy działający sandbox zawiera pełny zestaw narzędzi Node lub Python, a każde środowisko robocze przechowuje własne drzewo zależności na dysku. W przypadku braku zasobów na hoście, mechanizm pressure reaper w sandboxd zatrzymuje środowiska w celu zwolnienia pamięci, a procesy przekraczające limit pamięci kontenera są przerywane przez jądro systemu: docker ps -a wskazuje w takim przypadku kod wyjścia 137.
Czym sandboxd różni się od Dify lub OpenHands?
Narzędzia te generują odmienne artefakty. Dify tworzy aplikacje wywołujące model w czasie rzeczywistym, takie jak interfejsy czatowe czy potoki wyszukiwania informacji. OpenHands modyfikuje istniejące repozytorium, wykonując polecenia i proponując zmiany w kodzie źródłowym. sandboxd generuje zupełnie nowy projekt na podstawie promptu, buduje go wewnątrz dedykowanego kontenera i udostępnia pod adresem URL podglądu; rezultatem jest standardowa aplikacja internetowa, która do działania nie wymaga modelu.
Gdzie fizycznie znajduje się kod tworzony przez agenta?
Kod przechowywany jest w systemie plików hosta, a nie wewnątrz obrazu kontenera. Każda aplikacja otrzymuje katalog w /var/lib/sandboxed/workspaces/<id>/, który jest montowany (bind mount) do jej środowiska sandbox, gdzie pliki są widoczne w /home/sandbox/workspace/app. Stan płaszczyzny sterowania zapisywany jest w pojedynczym pliku SQLite w state/, w tym samym katalogu danych. Zmiany można zatwierdzać i wypychać do zdalnego repozytorium git za pomocą karty Git w konsoli lub poprzez punkty końcowe /v1/apps/<id>/git/commit i /git/push. Tokeny dla prywatnych repozytoriów są przechowywane w formie zaszyfrowanej przez płaszczyznę sterowania i nie są przekazywane bezpośrednio do środowiska sandbox.
Czy wystawienie sandboxd do Internetu jest bezpieczne?
Należy udostępniać wyłącznie adresy URL podglądu oraz konsolę; nigdy nie należy wystawiać API płaszczyzny sterowania. API to zarządza Docker na hoście, co jest równoważne z dostępem root, dlatego domyślnie powiązane jest z 127.0.0.1:9090. Środowiska sandbox w wersji self-hosted mają otwarty ruch wychodzący, co oznacza, że kod tworzony przez agenta może uzyskać dostęp do sieci lokalnej oraz punktów końcowych metadanych chmury. W przypadku posiadania w sieci innych istotnych zasobów należy skonfigurować reguły firewalla na hoście. W przypadku obsługi promptów od użytkowników niezaufanych zaleca się uruchamianie jednego hosta na jednego najemcę (tenant), zamiast polegać wyłącznie na izolacji kontenerowej.