−25%

Windows 연간 결제, 10월 31일까지. 요금제 보기

EQVPS
시작하기

CI용 샌드박스: 실행당 1센트도 안 되는 격리된 테스트 실행

신뢰할 수 없는 코드의 테스트(낯선 사람의 pull request, 자동 생성된 패치)를 실행 후 삭제되는 새 microVM에서 돌리세요. 초 단위 과금, Python과 TS SDK, 동시 실행 제한에 대한 솔직한 설명까지 담았습니다.

self-hosted CI runner에는 곤란한 특성이 하나 있습니다. 모든 것을 기억한다는 점입니다. 캐시, 토큰, 누군가 지난봄에 "임시로" 추가한 배포 키까지요. 우리 브랜치라면 괜찮습니다. 문제는 한 번도 들어 본 적 없는 사람이 pull request를 보냈을 때, 혹은 아직 아무도 읽지 않은 패치를 우리 AI 에이전트가 작성했을 때 시작됩니다.

깔끔한 답은 실행마다 머신 한 대를 쓰는 것입니다. 클론하고, 설치하고, 테스트하고, 머신을 버립니다.

실행은 이렇게 진행됩니다

샌드박스는 Python 3.12, Node.js 22, git, curl을 갖추고 약 1초 만에 시작되는 Firecracker microVM입니다. 외부로 나가는 인터넷은 되므로 git clone과 pip install -r requirements.txt가 평소처럼 동작합니다. 들어오는 포트는 없습니다. 실행 중인 테스트 환경에 외부에서 접속할 수 없습니다.

CI 작업 입장에서는 전체가 짧은 스크립트 하나입니다. 어느 CI 작업에서나 호출할 수 있는 Python SDK 버전은 다음과 같습니다.

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)

토큰은 CI 시크릿에 EQVPS_API_KEY로 저장합니다. 배포 키나 클라우드 자격 증명 등 CI의 다른 것은 샌드박스에 들어가지 않습니다. with 블록이 끝나면 샌드박스가 삭제되며, 작업이 중간에 실패해도 마찬가지입니다.

테스트 실행 자체는 백그라운드 작업입니다. 동기 명령 하나는 55초에서 멈추기 때문입니다. 백그라운드 작업은 실행 중에 출력을 스트리밍하고 샌드박스의 TTL까지 계속될 수 있습니다. 여기서는 멈춘 테스트 때문에 요금이 불어나지 않도록 30분으로 설정했습니다.

실제로 마주칠 제한

이걸 솔직하게 알려 드리면 오후 한나절을 아낄 수 있습니다.

동시 실행. 계정은 샌드박스를 20개까지 가질 수 있지만, 동시에 실행되는 명령은 2개뿐입니다. CI에서는 진짜로 병렬로 도는 작업이 2개라는 뜻입니다. 한꺼번에 들어온 PR 10개는 대기열에 들어갑니다. 파이프라인이 테스트를 워커 16개로 나눈다면 메인 파이프라인에는 맞지 않는 도구입니다. 메인은 VPS의 자체 runner에 두고, 신뢰할 수 없는 레인에만 샌드박스를 쓰세요.

내부에서 컨테이너를 쓸 수 없습니다. 샌드박스에는 Docker가 없습니다. Postgres 컨테이너가 필요한 단위 테스트와 통합 테스트는 그대로는 동작하지 않지만, SQLite나 메모리 내 가짜 객체를 쓰는 테스트는 동작합니다.

파일. API를 통한 업로드와 다운로드는 파일당 최대 5 MB입니다. 압축 파일을 올리지 말고 샌드박스 안에서 git으로 코드를 받으세요.

비용

요금제의 vCPU와 RAM을 초 단위, 최소 60초로 선불 잔액에서 지불합니다. 구독은 필요 없습니다.

실행요금제대략적인 비용
Lint + 단위 테스트, 1분small (0.5 vCPU, 1 GB)$0.0006
전체 스위트, 3분standard (1 vCPU, 2 GB)$0.0033
빌드 + 테스트, 10분plus (2 vCPU, 4 GB)$0.022

이 가격대에서 중요한 질문은 비용이 아니라, 설정한 시간 안에 테스트가 끝나느냐입니다. 가장 느린 성공 실행보다 조금 여유 있게 TTL을 잡으세요.

합리적인 역할 분담

권장하는 방식은 이렇습니다. 신뢰할 수 있는 브랜치는 캐시가 있는 빠른 runner에 그대로 둡니다. 직접 작성하지 않은 모든 것, 즉 포크, 외부 기여자, 에이전트가 생성한 패치는 먼저 샌드박스를 거치게 합니다. 샌드박스 실행이 성공하고 사람이 diff를 확인했다면, 신뢰하는 파이프라인으로 올립니다.

이렇게 하면 속도와 캐시가 중요한 레인과 깨끗한 머신이 중요한 레인을 나눌 수 있고, 도구 하나에 두 역할을 억지로 맡기지 않아도 됩니다.

샌드박스 개요와 연결 가이드부터 시작하세요. 새 계정에는 샌드박스 사용 시간 $1이 제공되며, 짧은 테스트라면 수백 번 실행할 수 있습니다. 위에서 쓴 메서드는 모두 SDK 레퍼런스에, 정확한 과금 규칙은 샌드박스 제한과 과금에 있습니다.

관련 글: 코드 리뷰와 PR 검사를 위한 샌드박스, AI 에이전트용 샌드박스.

배포할 준비가 되셨나요? 암호화폐로 결제, KYC 없음 — 약 1분 만에 온라인.

지금 배포 →

FAQ

신뢰할 수 없는 pull request를 제 self-hosted runner에서 돌리면 안 되는 이유는 무엇인가요?

self-hosted runner는 작업 사이에 상태를 유지하고, 보통 배포 키나 클라우드 자격 증명을 가지고 있습니다. 모르는 사람이 보낸 pull request는 한 단계 만에 이를 읽을 수 있습니다. 샌드박스는 매번 깨끗한 상태로 시작하며 테스트 대상 코드 외에는 아무것도 없습니다.

테스트를 55초보다 오래 실행할 수 있나요?

네. 55초 제한은 동기 명령 하나에 적용됩니다. 테스트 스위트를 백그라운드 작업으로 시작하고 출력을 주기적으로 확인하면, 샌드박스 수명이 끝날 때까지 실행할 수 있습니다. 임시 샌드박스는 최대 24시간입니다.

테스트를 몇 개까지 병렬로 실행할 수 있나요?

계정당 샌드박스는 최대 20개지만, 동시에 실행되는 명령은 계정당 2개뿐입니다. CI에서는 실제로 동시에 도는 작업이 2개이고 나머지는 대기열에 들어간다는 뜻입니다. 넓은 병렬 샤딩이 필요하다면 VPS의 runner 무리가 더 적합합니다.

샌드박스 안에서 Docker를 쓸 수 있나요?

샌드박스에는 Python 3.12, Node.js 22, bash, git, curl이 들어 있고, 의존성은 pip이나 npm으로 설치합니다. Docker는 포함되어 있지 않습니다. 테스트가 컨테이너를 띄운다면 VPS의 runner에서 실행하세요.

실행 한 번에 비용이 얼마인가요?

요금제의 vCPU와 RAM에 대해 초 단위, 최소 60초로 과금됩니다. standard 요금제(1 vCPU, 2 GB)에서 3분 실행하면 약 $0.0033입니다.

댓글

아직 댓글이 없습니다. 첫 번째가 되세요.

댓글 남기기

댓글은 표시되기 전에 검토됩니다.