본문으로 건너뛰기

샌드박스에 배포

@mastra/deployer-sandboxStudio를 포함한 전체 Mastra 서버를 임시 작업 공간 샌드박스에 배포하고 라이브 공개 URL을 반환합니다. 배포자가 종속성 설치를 건너뛰기 때문에 반복 배포가 더 빨리 완료될 수 있습니다.

다음과 같은 경우 샌드박스 배포를 사용하세요.

  • Agent 구축 앱: Agent는 Mastra 프로젝트를 생성하고 배포하여 결과를 확인합니다.
  • 지속적 통합(CI): 점검을 위해 실제 서버를 가동한 후 해체합니다.
  • 즉시 미리보기: 병합하기 전에 작업 중인 Agent를 팀과 공유하세요.
  • 신뢰할 수 없는 다중 테넌트 코드: 인프라에서 격리된 사용자별 Mastra 인스턴스를 실행합니다.

샌드박스에는 공급자가 적용하는 런타임 한도가 있으며 만료됩니다. 프로덕션 호스팅에 대해서는 다음을 참조하세요.deployment overview.

지원되는 샌드박스
지원되는 샌드박스에 대한 직접 링크

배포자는 네트워킹(공용 포트 URL)을 지원하는 모든 작업 공간 샌드박스에서 작동합니다.

Provider 작성자는 WorkspaceSandbox의 선택적 networking 기능을 구현해 지원을 추가할 수 있습니다.

빠른 시작
빠른 시작에 대한 직접 링크

원하는 배포자와 샌드박스 공급자를 설치합니다. 이 예에서는 Vercel Sandbox를 사용합니다.

npm install @mastra/deployer-sandbox @mastra/vercel

src/mastra/index.ts 파일에서 배포자를 구성하세요. sandboxName은 배포를 식별하므로 이후에 동일한 이름으로 배포하면 기존 Sandbox를 재사용합니다.

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'
import { SandboxDeployer } from '@mastra/deployer-sandbox'
import { VercelSandbox } from '@mastra/vercel'

export const mastra = new Mastra({
deployer: new SandboxDeployer({
sandbox: new VercelSandbox({
sandboxName: 'my-preview',
timeout: 2_400_000, // 40 minutes
ports: [4111],
}),
}),
})

두 가지 Vercel 관련 요구사항:

  • timeout은 Pro 요금제의 최대 Sandbox 수명인 45분을 초과할 수 없습니다. 더 큰 값을 사용하면 Vercel API에서 400 오류가 발생해 배포가 실패합니다.
  • 서버 포트를 ports에 선언하세요. E2B 및 Daytona와 달리 Vercel은 생성 시 선언된 포트만 노출합니다. 하나의 명령으로 빌드 및 배포:
mastra build

SandboxDeployer()가 구성되면 mastra build가 프로젝트를 번들링해 Sandbox에 배포합니다. 배포 과정에서 API 및 Studio URL을 출력하고 .mastra/outputsandbox-deployment.json 매니페스트를 작성합니다.

API: https://<sandbox-id>-4111.vercel.run/api
Studio: https://<sandbox-id>-4111.vercel.run

Sandbox Provider가 만료 시간을 보고하면 매니페스트에 expiresAt이 포함됩니다. 동일한 Sandbox에 다시 배포할 때 입력이 변경되지 않았다면 종속성 설치를 건너뜁니다. 이러한 입력에는 package.json, 번들에 포함된 잠금 파일, 설치 명령이 포함됩니다.

URL의 역할
URL의 역할에 대한 직접 링크

Studio URL은 Sandbox 루트이며 /api가 아닙니다. Studio를 사용하려면 브라우저에서 여세요. studio: false로 배포하면 루트에 Studio 대신 Mastra 시작 페이지가 표시됩니다. API URL은 /api/agents 아래 엔드포인트의 접두사일 뿐입니다. /api 자체에는 핸들러가 없으므로 서버가 정상이어도 브라우저에서 열면 "Not Found" 응답이 반환됩니다. 배포를 확인하려면 엔드포인트를 직접 호출하세요.

curl -s -X POST https://4111-<sandbox-id>.e2b.app/api/agents/weatherAgent/generate \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"Weather in London"}]}' | jq -r '.text'

공급자 자격 증명
공급자 자격 증명에 대한 직접 링크

각 공급자는 자체 자격 증명으로 인증합니다. 배포할 샌드박스에 대한 항목을 설정합니다.

.env
# E2B
E2B_API_KEY=

# Daytona
DAYTONA_API_KEY=

# Vercel
VERCEL_TOKEN=
VERCEL_TEAM_ID=
VERCEL_PROJECT_ID=

모든 Provider에서 이를 생성자 옵션으로 전달할 수도 있습니다. 자체 호스팅 E2B 및 Daytona 설치에는 E2B_DOMAIN 또는 DAYTONA_API_URL을 사용하세요. mastra dev와 달리 mastra build.env 파일을 로드하지 않습니다. 배포는 빌드 내부에서 이루어지므로 E2B의 E2B_API_KEY처럼 환경에서 자격 증명을 읽는 Sandbox Provider에는 빈 값이 전달되고, 배포는 인증 오류로 실패합니다. src/mastra/index.tsimport 'dotenv/config'를 추가해도 문제가 해결되지 않습니다. 빌드는 배포자를 찾기 위해 진입점 파일에서 deployer 옵션만 추출하고 해당 import를 포함한 나머지는 모두 트리 셰이킹으로 제거합니다. 빌드가 실행되기 전에 .env 파일을 셸 환경으로 로드하세요. dotenv-cli를 사용하는 방법이 있습니다.

npm install --save-dev dotenv-cli
package.json
{
"scripts": {
"deploy": "dotenv -e .env -- mastra build"
}
}

그런 다음 npm run deploy를 실행하세요. SandboxDeployer()가 구성되면 mastra build가 배포까지 수행하므로 스크립트 이름은 실제 동작에 맞게 지정되었습니다. 호스팅 플랫폼이나 CI 작업에서 npm run build를 실행할 때 실수로 Sandbox를 배포하지 않도록 일반 build 스크립트와 분리해 두세요. CI(지속적 통합)에서는 대신 자격 증명을 비밀로 내보냅니다. 어떤 메커니즘을 사용하든 변수는 쉘 환경뿐만 아니라 쉘 환경에도 존재해야 합니다..env file.

이는 배포자 머신에 필요한 자격 증명에 적용됩니다. 배포된 서버에 필요한 변수는 별도로 처리됩니다. 배포자는 .env, .env.production, .env.local을 읽어 Sandbox에 삽입합니다. 보안을 참조하세요.

E2B 사용
E2B 사용에 대한 직접 링크

E2B의 경우 id는 배포를 식별하므로, 이후 같은 값을 사용해 배포하면 실행 중이든 일시 중지 상태이든 기존 Sandbox에 다시 연결됩니다.

src/mastra/index.ts
import { SandboxDeployer } from '@mastra/deployer-sandbox'
import { E2BSandbox } from '@mastra/e2b'

const deployer = new SandboxDeployer({
sandbox: new E2BSandbox({
id: 'my-preview',
template: 'base',
timeout: 3_600_000, // 1 hour
}),
})

파일 시스템 마운트가 필요하지 않다면 template: 'base'를 전달하세요. 이를 전달하지 않으면 Provider가 처음 사용할 때 사용자 공간 파일 시스템(FUSE) 커스텀 템플릿을 빌드합니다. E2B는 중지하는 대신 일시 중지합니다. stop()은 Memory와 실행 중인 프로세스를 포함한 가상 머신(VM) 전체의 스냅샷을 생성합니다. 일시 중지된 Sandbox가 다시 활성화되면 Mastra 서버는 중단된 지점부터 재개되며, Vercel에서처럼 다시 실행하는 단계가 없습니다.

데이토나 사용
데이토나 사용에 대한 직접 링크

Daytona의 경우 id는 배포를 식별하므로, 이후 같은 값을 사용해 배포하면 기존 Sandbox에 다시 연결됩니다. 토큰 없이 미리 보기 URL에 접근할 수 있게 하려면 public: true를 설정하세요.

src/mastra/index.ts
import { SandboxDeployer } from '@mastra/deployer-sandbox'
import { DaytonaSandbox } from '@mastra/daytona'

const deployer = new SandboxDeployer({
sandbox: new DaytonaSandbox({
id: 'my-preview',
public: true,
autoStopInterval: 30, // minutes
}),
})

Daytona 샌드박스를 중지하면 파일 시스템은 유지되지만 프로세스는 실행되지 않으므로 깨우기는 Vercel처럼 작동합니다. 확인자는 서버를 다시 시작합니다.wake: true.

Daytona는 대상별로 아웃바운드 트래픽을 필터링합니다. 일부 호스트에 대한 요청은 일반적으로 전송 계층 보안(TLS)을 통해 연결되지만, 다른 호스트에 대한 요청은 핸드셰이크 중 재설정됩니다. Agent나 Tool에는 일반적인 Node 오류인 fetch failed로 표시됩니다. 이를 디버깅하기 전에 코드 문제를 배제하려면 Sandbox 내부에서 같은 호스트를 대상으로 curl을 실행하세요.

const sandbox = new DaytonaSandbox({ id: 'my-preview' })
await sandbox.start()

const result = await sandbox.executeCommand('curl -v --max-time 10 https://api.example.com')
console.info(result.stdout, result.stderr)

TLS 핸드셰이크 중 발생하는 Connection reset by peer는 Agent가 아니라 필터링이 원인임을 나타냅니다. Daytona 지원팀에 해당 대상의 허용을 요청하세요. 제한된 Daytona 요금제에서는 클라우드 스토리지 엔드포인트도 차단되며, 마운트 헬퍼는 이를 전용 오류로 보고합니다.

프로그래밍 방식으로 배포
프로그래밍 방식으로 배포에 대한 직접 링크

deployToSandbox()는 번들러 없이 미리 빌드된 출력 디렉터리를 배포합니다. SandboxDeployer()와 달리 studio: true를 전달하지 않으면 Studio가 포함되지 않습니다. CI 또는 Agent 코드에서 사용하세요.

import { deployToSandbox } from '@mastra/deployer-sandbox'
import { VercelSandbox } from '@mastra/vercel'

const deployment = await deployToSandbox({
sandbox: new VercelSandbox({ sandboxName: 'ci-smoke', ports: [4111] }),
dir: '.mastra/output',
})

console.info(deployment.url) // https://<sandbox-id>-4111.vercel.run
await deployment.logs() // tail the server log
await deployment.stop() // stop the sandbox (resumable)
await deployment.destroy() // permanently delete the sandbox

수명주기
수명주기에 대한 직접 링크

배포 관리
배포 관리에 대한 직접 링크

서버에서만 사용할 수 있는 @mastra/deployer-sandbox/clientgetDeployment() export를 사용하여 기존 배포를 가져오세요. 이 함수는 Vercel의 sandboxName이나 E2B 또는 Daytona의 id 같은 Provider별 설정을 통해 Sandbox를 식별합니다. 조회는 배포를 생성한 프로세스에 종속되지 않으므로 다른 서버 측 서비스나 CI에서도 사용할 수 있습니다.

scripts/stop.ts
import { getDeployment } from '@mastra/deployer-sandbox/client'
import { VercelSandbox } from '@mastra/vercel'

const deployment = await getDeployment({
sandbox: new VercelSandbox({ sandboxName: 'my-preview', ports: [4111] }),
port: 4111,
})

console.info(deployment.status, deployment.url)
await deployment.logs() // tail the server log
await deployment.stop() // stop the sandbox (resumable)
await deployment.destroy() // permanently delete the sandbox

중지된 Sandbox를 반환하기 전에 재개하려면 wake: true를 전달하세요. 재개 후 서버가 정상 상태가 아닐 때만 서버를 다시 실행합니다. vercel sandbox ls, vercel sandbox stop, vercel sandbox rm 같은 Provider 도구도 사용할 수 있습니다.

만료 및 URL
만료 및 URL에 대한 직접 링크

Sandbox는 Provider의 런타임 제한에 따라 만료됩니다. Provider가 만료 시간을 보고하면 배포에서 이를 기록하며, deployment.expiresAt을 통해 프로그래밍 방식으로 확인할 수 있습니다. Sandbox를 중지했다가 다시 시작하면 Sandbox URL이 변경될 수 있습니다. URL은 연결 정보로 취급하고 Sandbox ID(예: sandboxName)를 안정적인 핸들로 사용하세요. 아래의 라우팅 계층에서는 URL 변경을 처리합니다.

라우팅 계층
라우팅 계층에 대한 직접 링크

계층 1: 직접 URL
계층 1: 직접 URL에 대한 직접 링크

배포 시 새로운 URL이 허용되는 개발, 데모 및 CI에는 인쇄된 URL을 직접 사용하세요.

계층 2: 런타임에 해결
계층 2: 런타임에 해결에 대한 직접 링크

getDeployment()런타임 시 현재 URL을 확인하므로 소비자는 오래된 URL을 보유하지 않습니다. Mastra 프로젝트와 다른 코드베이스에 있는 서버를 포함하여 샌드박스 이름을 알고 있는 모든 서버가 이를 해결할 수 있습니다.

app/api/agent-url/route.ts
import { getDeployment } from '@mastra/deployer-sandbox/client'
import { VercelSandbox } from '@mastra/vercel'

const deployment = await getDeployment({
sandbox: new VercelSandbox({ sandboxName: 'my-preview', ports: [4111] }),
wake: true,
})

console.info(deployment.url, deployment.status)

wake: false(기본값)를 사용하면 Sandbox를 시작하지 않고 조치에 필요한 { url, status }를 반환합니다. URL 확인, stop(), destroy()는 Sandbox를 재개하지 않고 이름으로 기존 Sandbox에 연결하므로, 중지된 Sandbox에서 수명 주기 작업을 수행해도 Sandbox가 활성화되거나 요금이 부과되기 시작하지 않습니다. wake: true를 사용하면 Sandbox가 재개되고, 서버가 응답하지 않을 경우 다시 실행됩니다. 다시 실행해야 하는지는 Provider에 따라 다릅니다. Vercel과 Daytona는 파일 시스템을 복원하지만 실행 중인 프로세스는 복원하지 않는 반면, E2B는 서버 프로세스를 포함한 VM 전체를 재개합니다.

경고

@mastra/deployer-sandbox/client서버 전용입니다. 샌드박스를 해결하려면 브라우저에 절대 도달해서는 안 되는 공급자 자격 증명을 사용합니다. 브라우저 컨텍스트에서 가져온 경우 모듈이 발생합니다.

계층 3: 최종 사용자를 위한 안정적인 URL
계층 3: 최종 사용자를 위한 안정적인 URL에 대한 직접 링크

최종 사용자에게 자신의 도메인에 안정적인 URL을 제공하고 경로 처리기 프록시 또는 Edge Config 별칭을 사용하여 샌드박스 서버측으로 전달합니다.

아래 예는 Vercel 및 Next.js 설정을 보여주지만 이 개념은 요청을 전달할 수 있는 모든 서버 측 프레임워크 또는 공급자에 적용됩니다.

  • 경로 핸들러 프록시. createSandboxHandler()는 Sandbox URL을 캐시하고 연결 수준 오류가 발생하면 URL을 다시 확인하여 URL 변경과 콜드 웨이크를 처리합니다.

    app/api/[...path]/route.ts
    import { createSandboxHandler, getDeployment } from '@mastra/deployer-sandbox/client'
    import { VercelSandbox } from '@mastra/vercel'

    const handler = createSandboxHandler({
    resolve: async () => {
    const deployment = await getDeployment({
    sandbox: new VercelSandbox({ sandboxName: 'my-preview', ports: [4111] }),
    wake: true,
    })
    return deployment.url!
    },
    })

    export { handler as GET, handler as POST }
  • Edge Config 별칭. 배포할 때마다 Vercel Edge Config 항목이 현재 URL을 가리키도록 유지하려면 배포자에서 alias 옵션을 설정하세요.

    src/mastra/index.ts
    const deployer = new SandboxDeployer({
    sandbox: new VercelSandbox({ sandboxName: 'my-preview', ports: [4111] }),
    alias: { edgeConfigId: 'ecfg_...', key: 'my-preview', token: process.env.VERCEL_TOKEN! },
    })

    그런 다음 Next.js 미들웨어에서 요청을 다시 작성합니다.createSandboxProxy():

    middleware.ts
    import { createSandboxProxy } from '@mastra/deployer-sandbox/client'

    export const middleware = createSandboxProxy({ key: 'my-preview' })
    export const config = { matcher: '/api/:path*' }

CI 예시
CI 예시에 대한 직접 링크

모든 끌어오기 요청에 미리보기를 배포합니다.

.github/workflows/preview.yml
name: Sandbox preview
on: pull_request

jobs:
preview:
runs-on: ubuntu-latest
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_TEAM_ID: ${{ secrets.VERCEL_TEAM_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx mastra build
- run: curl --fail "$(jq -r .url .mastra/output/sandbox-deployment.json)/api"

보안
보안에 대한 직접 링크

  • Sandbox URL은 공개됩니다. URL을 아는 사람은 누구나 Studio를 포함한 Mastra 서버에 연결할 수 있습니다. 일회성 미리 보기 이외의 용도라면 서버 인증을 활성화하세요.
  • .env 파일의 환경 변수는 서버가 실행될 수 있도록 원격 Sandbox VM에 주입됩니다. 이 경우 배포 과정에서 경고를 기록합니다. 공유 미리 보기 서버에 두지 않을 비밀 정보는 배포하지 마세요.
  • Tier 3 트래픽의 접근을 제한하려면 createSandboxHandler() 또는 createSandboxProxy()secret을 전달하세요. 헬퍼는 전달되는 요청의 x-mastra-sandbox-secret 헤더에 이를 첨부합니다. 해당 헤더를 요구하도록 서버 인증을 구성하면 Sandbox URL로 직접 접근하는 요청은 거부되고 도메인을 통과하는 트래픽은 정상적으로 작동합니다.