Runnery CI self-hosted mają jedną niewygodną cechę: wszystko pamiętają. Cache, tokeny, klucz wdrożeniowy, który ktoś dodał „tymczasowo” zeszłej wiosny. Dla własnych gałęzi to nie problem. Problem pojawia się, gdy przychodzi pull request od kogoś, o kim nigdy nie słyszałeś — albo od twojego własnego agenta AI, który napisał poprawkę, której nikt jeszcze nie przeczytał.
Czysta odpowiedź to osobna maszyna na każdy przebieg. Sklonować, zainstalować, przetestować, wyrzucić maszynę.
Jak wygląda przebieg
Sandbox to microVM Firecracker, która startuje w około sekundę z Pythonem 3.12, Node.js 22, git i curl. Ruch wychodzący do internetu działa, więc git clone i pip install -r requirements.txt zachowują się jak zwykle. Nie ma portów przychodzących — nic nie może połączyć się ze środowiskiem testowym, dopóki działa.
Z zadania CI całość to krótki skrypt. Oto on z SDK dla Pythona, wywoływany z dowolnego zadania CI:
import os, sys
from eqvps import Sandbox
repo, ref = os.environ["REPO_URL"], os.environ["PR_SHA"]
with Sandbox.create(tariff="standard", ttl=1800) as sb:
sb.exec(f"git clone {repo} /root/app && cd /root/app && git checkout {ref}", timeout=55)
sb.exec("cd /root/app && pip install -r requirements.txt", timeout=55)
task = sb.exec("cd /root/app && python3 -m pytest -q", background=True)
result = task.wait(on_output=lambda out, err: print(out, end=""))
sys.exit(result.exit_code or 0)
Token leży w sekretach CI jako EQVPS_API_KEY. Nic innego z twojego CI — ani klucze wdrożeniowe, ani dane dostępowe do chmury — nie trafia do sandboxa. Gdy kończy się blok with, sandbox jest usuwany, także jeśli zadanie padło w połowie.
Sam przebieg testów to zadanie w tle, bo pojedyncze polecenie synchroniczne zatrzymuje się po 55 sekundach. Zadanie w tle przesyła wyjście na bieżąco i może trwać do TTL sandboxa — tu ustawionego na 30 minut, żeby zawieszony test nie nabił rachunku.
Limity, na które naprawdę trafisz
Uczciwe powiedzenie o nich oszczędzi ci popołudnie.
Współbieżność. Konto może mieć 20 sandboxów, ale tylko 2 polecenia wykonują się jednocześnie. W CI to dwa zadania działające naprawdę równolegle. Dziesięć PR-ów, które przyjdą naraz, ustawi się w kolejce. Jeśli twój pipeline dzieli testy na 16 workerów, to złe narzędzie dla głównego pipeline'u — zostaw go na własnych runnerach na VPS, a sandboxów używaj dla niezaufanego pasa.
Bez kontenerów w środku. Docker nie jest dostarczany w sandboxie. Testy jednostkowe i integracyjne, które potrzebują kontenera Postgres, nie zadziałają bez zmian; testy na SQLite albo na atrapie w pamięci — zadziałają.
Pliki. Wysyłanie i pobieranie przez API to maksymalnie 5 MB na plik. Pobieraj kod przez git wewnątrz sandboxa zamiast wysyłać archiwum.
Ile to kosztuje
Płacisz za vCPU i RAM taryfy za sekundę, minimum 60 sekund, z przedpłaconego salda — bez abonamentu.
| Przebieg | Taryfa | Przybliżony koszt |
|---|---|---|
| Linter + testy jednostkowe, 1 min | small (0.5 vCPU, 1 GB) | $0.0006 |
| Pełny zestaw, 3 min | standard (1 vCPU, 2 GB) | $0.0033 |
| Budowanie + testy, 10 min | plus (2 vCPU, 4 GB) | $0.022 |
Przy takich cenach ciekawe pytanie to nie koszt, tylko czy testy zmieszczą się w ustawionym czasie. Daj TTL trochę zapasu ponad twój najwolniejszy zielony przebieg.
Rozsądny podział
Nasza rekomendacja: zaufane gałęzie zostaw na swoim szybkim runnerze z cache. Wszystko, czego nie napisałeś sam — forki, zewnętrznych kontrybutorów, poprawki od agentów — najpierw przepuść przez sandbox. Jeśli przebieg w sandboxie jest zielony, a człowiek obejrzał diff, przenieś go do zaufanego pipeline'u.
Masz wtedy jeden pas, gdzie liczą się szybkość i cache, i drugi, gdzie liczy się czysta maszyna, bez zmuszania jednego narzędzia do bycia jednym i drugim.
Zacznij od przeglądu sandboxów i przewodnika po połączeniu — nowe konta dostają $1 czasu sandboxów, co wystarcza na kilkaset krótkich przebiegów. Każda użyta wyżej metoda jest w dokumentacji SDK, a dokładne zasady rozliczeń w limitach i rozliczeniach sandboxów.
Powiązane: sandbox do code review i sprawdzania PR oraz sandbox dla agentów AI.
Komentarze
Brak komentarzy. Bądź pierwszy.