Skip to content

Chapter 18 · Standalone Deployment and Server-Side ​

Chapter goals: Master Mastra's three deployment shapes — dev server, Node standalone, and Serverless — and understand the storage and state considerations for each.

18.1 Three Runtime Shapes ​

ShapeCommand / MethodUse Case
Devmastra devLocal development,自带 Studio (default :4111)
Node standalonenode dist/index.mjsSelf-managed server / Docker, full features
ServerlessVercel / Vercel-like platformsElastic scaling; watch for statefulcapabilities

18.2 Dev Server ​

bash
npm run dev        # Internally runs mastra dev
# Open http://localhost:4111 for Mastra Studio:
# Visual debugging for agents / workflows / traces / evals

18.3 Node Standalone Deployment (Docker) ​

dockerfile
# Dockerfile
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build        # Produces dist/

FROM node:22-slim
WORKDIR /app
COPY --from=build /app ./
EXPOSE 4111
CMD ["node", "dist/index.mjs"]
typescript
// src/index.ts —— production entry

[truncated - see source for full content]

Key point: do not use file: local databases in containers — multiple replicas would each写 their own. Use Postgres or Turso instead:

typescript
storage: new PgStore({ connectionString: process.env.DATABASE_URL })

18.4 Serverless Considerations ​

Serverless functions have no local disk and may freeze-restart at any time, so:

  1. Storage must be external — LibSQL cloud (Turso) or Postgres;
  2. Suspend/resume depends on snapshots — the persistence config from Chapter 13 is mandatory here;
  3. Background proxies are受限 — Observational Memory's background tasks are unreliable in short-lived functions;
  4. Cold starts — lazy-load agents on demand; avoid pulling the full model目录 at init.

18.5 Production Entry and Env Validation ​

Fail-fast on startup to avoid deploying with missing config:

typescript
// src/env.ts —— refuse to start if key vars are missing
const required = ['LIBSQL_URL', 'LIBSQL_AUTH_TOKEN', 'OPENAI_API_KEY'] as const
for (const key of required) {
  if (!process.env[key]) {
    console.error(`Missing env var: ${key}`)
    process.exit(1)
  }
}
export const env = { LIBSQL_URL: process.env.LIBSQL_URL! }
typescript
// src/server.ts —— explicitly specify listen port and host
import { createServer } from 'node:http'
import { mastra } from './mastra'
import './env'

const port = Number(process.env.PORT ?? 4111)
createServer(mastra.getServerHandler?.() ?? undefined)
console.log(`Mastra service started: http://0.0.0.0:${port}`)

18.6 Deployment Verification Checklist ​

bash
# Smoke test: health check + one real call
curl -s https://your-host/healthz
curl -s -X POST https://your-host/api/agents/support/generate \
  -H 'Content-Type: application/json' \
  -d '{"messages":[{"role":"user","content":"Hello"}]}'

Confirm: env vars complete, storage connected, traces exporting correctly, Studio closed or access-controlled.

18.7 Chapter Summary ​

  • Three shapes: dev (mastra dev), Node standalone (node dist/index.mjs), Serverless (Vercel etc.);
  • Never use local file: databases in containers — use Postgres/Turso;
  • Serverless requires external storage, explicit suspend/resume persistence, and lazy agent loading;
  • Fail-fast env validation + smoke测试 before going live.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. Why can you not use file: databases in a containerized deployment?

2. What is mandatory for suspend/resume in a Serverless deployment?

3. What does the fail-fast env validation prevent?

4. Why should agents be lazy-loaded in Serverless?

🛠️ Hands-On Exercises ​

  1. Build a Docker image for your Mastra app using the Dockerfile above; run it and verify the health endpoint.
  2. Deploy to a Serverless platform (Vercel); configure Turso as external storage; verify suspend/resume works across function restarts.
  3. Add env validation to your production entry;故意 remove one required var and verify the process exits with a clear error.

Next: Chapter 19 · Capstone 1: Production-Grade Smart Customer Service Agent