Mastra Worker をデプロイする
Mastra Worker を別プロセスとして実行し、Orchestration、Schedule、バックグラウンドタスクを API とは独立してスケーリングします。このガイドでは、Docker Compose または Kubernetes を使用した完全分離型のデプロイについて説明します。
このガイドでは、Worker を独自のコンテナに分離する方法を説明します。API と同じプロセス内で Worker を実行するだけでよい場合は、Worker を参照してください。追加設定は必要ありません。
始める前に始める前にへの直接リンク
次のものが必要です。
- Mastra アプリケーション
- Docker と Docker Compose、または
kubectlを使用できる Kubernetes Cluster - 分散 PubSub Backend:
RedisStreamsPubSub用の Redis、またはGoogleCloudPubSub用の Google Cloud プロジェクト - すべてのコンテナからアクセスできる共有データベース。完全な一覧は、サポートされるストレージ Backend を参照してください。
デフォルトの In-memory PubSub はプロセス間でイベントを配信できません。Worker を別のコンテナに分離する前に、分散 PubSub Backend を設定する必要があります。
共有インフラストラクチャを設定する共有インフラストラクチャを設定するへの直接リンク
Mastra インスタンスを分散 PubSub Backend と共有データベースに接続します。すべてのコンテナで同じイメージを実行できるように、環境変数を使用します。
- Redis Streams + PostgreSQL
- Google Cloud Pub/Sub + LibSQL
import { Mastra } from '@mastra/core/mastra'
import { RedisStreamsPubSub } from '@mastra/redis-streams'
import { PostgresStore } from '@mastra/pg'
export const mastra = new Mastra({
storage: new PostgresStore({
connectionString: process.env.DATABASE_URL!,
}),
pubsub: new RedisStreamsPubSub({
url: process.env.REDIS_URL!,
}),
})
import { Mastra } from '@mastra/core/mastra'
import { GoogleCloudPubSub } from '@mastra/google-cloud-pubsub'
import { LibSQLStore } from '@mastra/libsql'
export const mastra = new Mastra({
storage: new LibSQLStore({
url: process.env.DATABASE_URL!,
}),
pubsub: new GoogleCloudPubSub({
projectId: process.env.GCP_PROJECT_ID!,
}),
})
サポートされるストレージ Backend はどれでも使用できます。使用するデータベースに合わせてストレージ Adapter を置き換えてください。
デプロイするデプロイするへの直接リンク
Mastra アプリケーションをビルドします。出力はすべてのコンテナで実行されます。
mastra build自己完結型の
.mastra/output/ディレクトリが生成されます。ビルド出力について詳しくは、Mastra サーバーをデプロイするを参照してください。ビルド済み出力をコピーし、本番用の依存関係をインストールする Dockerfile を作成します。
app/DockerfileFROM node:22-alpineWORKDIR /appCOPY .mastra/output/package.json .mastra/output/.npmrc* ./RUN npm install --omit=devCOPY .mastra/output/ .EXPOSE 4111CMD ["node", "index.mjs"]完全分離型の Topology を定義します。この構成は、データベース、PubSub Backend、API サーバー、3 つの Worker の計 6 つの Service を実行します。各 Worker は同じイメージを異なる
MASTRA_WORKERS値で実行し、起動する Worker を制御します。API は
MASTRA_WORKERS: "false"を設定し、すべてのイベント処理を無効にします。Orchestration Worker はMASTRA_STEP_EXECUTION_URLを設定し、Step 実行リクエストを API の内部 URL に送ります。詳しくは Step 実行 URLを参照してください。すべての Service が
MASTRA_WORKER_AUTH_TOKENを共有します。Worker は API へのリクエストにこの Token を含めるため、API は呼び出し元が信頼できる内部 Service であることを検証できます。詳しくは Worker 認証を参照してください。- Docker Compose
- Kubernetes
docker-compose.ymlservices:postgres:image: postgres:16-alpineenvironment:POSTGRES_USER: mastraPOSTGRES_PASSWORD: ${POSTGRES_PASSWORD}POSTGRES_DB: mastraports:- '5432:5432'volumes:- pgdata:/var/lib/postgresql/datahealthcheck:test: ['CMD-SHELL', 'pg_isready -U mastra']interval: 5stimeout: 3sretries: 5redis:image: redis:7-alpineports:- '6379:6379'healthcheck:test: ['CMD', 'redis-cli', 'ping']interval: 5stimeout: 3sretries: 5api:build: ./appports:- '4111:4111'environment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: 'false'MASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:postgres:condition: service_healthyredis:condition: service_healthyhealthcheck:test: ['CMD', 'wget', '-qO-', 'http://localhost:4111/api/agents']interval: 5stimeout: 3sretries: 5orchestration-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: orchestrationMASTRA_STEP_EXECUTION_URL: http://api:4111/apiMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthyscheduler-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: schedulerMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthybackground-task-worker:build: ./appenvironment:DATABASE_URL: postgres://mastra:${POSTGRES_PASSWORD}@postgres:5432/mastraREDIS_URL: redis://redis:6379MASTRA_WORKERS: backgroundTasksMASTRA_WORKER_AUTH_TOKEN: ${MASTRA_WORKER_AUTH_TOKEN}depends_on:api:condition: service_healthyvolumes:pgdata:docker-compose.ymlと同じ場所に.envファイルを作成します。.envPOSTGRES_PASSWORD=your-secure-passwordMASTRA_WORKER_AUTH_TOKEN=your-shared-secret-token注記アプリケーションに必要なその他の環境変数(モデル Provider の API キーなど)も設定してください。
Namespace と接続文字列を含む Secret を作成します。
k8s/namespace.yamlapiVersion: v1kind: Namespacemetadata:name: mastra-workerskubectl apply -f k8s/namespace.yamlkubectl create secret generic mastra-secrets -n mastra-workers \--from-literal=POSTGRES_PASSWORD='your-password' \--from-literal=DATABASE_URL='postgresql://mastra:your-password@postgres:5432/mastra' \--from-literal=REDIS_URL='redis://redis:6379' \--from-literal=MASTRA_WORKER_AUTH_TOKEN='your-shared-token'注記アプリケーションに必要なその他の環境変数(モデル Provider の API キーなど)を Secret または追加の
--from-literalEntry として追加してください。Cluster から Pull できる Registry に Docker イメージをビルドしてプッシュします。
docker build -t your-registry/mastra-workers:latest ./appdocker push your-registry/mastra-workers:latestデータベース、PubSub Backend、API、3 つの Worker 用の Deployment と Service を適用します。次の例では、Cluster 内の Postgres と Redis を使用します。本番環境では、マネージド Service(Amazon RDS、Cloud SQL、ElastiCache、Memorystore など)を使用してください。
k8s/postgres.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: postgresnamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: postgrestemplate:metadata:labels:app: postgresspec:containers:- name: postgresimage: postgres:16-alpineports:- containerPort: 5432env:- name: POSTGRES_USERvalue: mastra- name: POSTGRES_PASSWORDvalueFrom:secretKeyRef:name: mastra-secretskey: POSTGRES_PASSWORD- name: POSTGRES_DBvalue: mastravolumeMounts:- name: pgdatamountPath: /var/lib/postgresql/datavolumes:- name: pgdataemptyDir: {}---apiVersion: v1kind: Servicemetadata:name: postgresnamespace: mastra-workersspec:selector:app: postgresports:- port: 5432targetPort: 5432注意上記の Postgres の例ではストレージに
emptyDirを使用しているため、Pod を再起動するとデータが失われます。本番環境ではPersistentVolumeClaimに置き換えるか、マネージドデータベース Service を使用してください。k8s/redis.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: redisnamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:- name: redisimage: redis:7-alpineargs: ['--appendonly', 'yes']ports:- containerPort: 6379---apiVersion: v1kind: Servicemetadata:name: redisnamespace: mastra-workersspec:selector:app: redisports:- port: 6379targetPort: 6379k8s/api.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: apinamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: apitemplate:metadata:labels:app: apispec:containers:- name: apiimage: your-registry/mastra-workers:latestports:- containerPort: 4111env:- name: MASTRA_WORKERSvalue: 'false'envFrom:- secretRef:name: mastra-secretsreadinessProbe:httpGet:path: /api/agentsport: 4111initialDelaySeconds: 10periodSeconds: 5livenessProbe:httpGet:path: /api/agentsport: 4111initialDelaySeconds: 15periodSeconds: 10resources:requests:cpu: 500mmemory: 512Mi---apiVersion: v1kind: Servicemetadata:name: apinamespace: mastra-workersspec:selector:app: apiports:- port: 4111targetPort: 4111k8s/orchestration-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: orchestration-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: orchestration-workertemplate:metadata:labels:app: orchestration-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: orchestration- name: MASTRA_STEP_EXECUTION_URLvalue: http://api:4111/apienvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mik8s/scheduler-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: scheduler-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: scheduler-workertemplate:metadata:labels:app: scheduler-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: schedulerenvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Mik8s/background-task-worker.yamlapiVersion: apps/v1kind: Deploymentmetadata:name: background-task-workernamespace: mastra-workersspec:replicas: 1selector:matchLabels:app: background-task-workertemplate:metadata:labels:app: background-task-workerspec:containers:- name: workerimage: your-registry/mastra-workers:latestenv:- name: MASTRA_WORKERSvalue: backgroundTasksenvFrom:- secretRef:name: mastra-secretsresources:requests:cpu: 250mmemory: 256Miすべての Manifest を適用し、API の準備ができるまで待ちます。
kubectl apply -f k8s/kubectl wait -n mastra-workers --for=condition=ready pod -l app=api --timeout=90skubectl wait -n mastra-workers --for=condition=ready pod -l app=orchestration-worker --timeout=60skubectl wait -n mastra-workers --for=condition=ready pod -l app=scheduler-worker --timeout=60skubectl wait -n mastra-workers --for=condition=ready pod -l app=background-task-worker --timeout=60sStack が実行され、API が応答することを確認します。
- Docker Compose
- Kubernetes
docker compose up -ddocker compose pscurl http://localhost:4111/api/agentskubectl get pods -n mastra-workerskubectl port-forward -n mastra-workers svc/api 4111:4111別のターミナルで次を実行します。
curl http://localhost:4111/api/agentsAgent の一覧が JSON で返れば、API と Worker は実行されています。
Step 実行 URLStep 実行 URLへの直接リンク
完全分離型のデプロイでは、Orchestration Worker が API とは別のコンテナで実行されます。Workflow イベントを処理するとき、HTTP 経由で Step の実行を API に委任します。
MASTRA_STEP_EXECUTION_URL に /api Prefix を含む API の内部 URL を設定します。
MASTRA_STEP_EXECUTION_URL=http://api:4111/api
Orchestration Worker は、Step ごとに ${MASTRA_STEP_EXECUTION_URL}/workflows/:workflowId/runs/:runId/steps/execute へ POST リクエストを送ります。API が Workflow を解決し、Step をローカル実行します。
この変数を設定しない場合、Orchestration Worker はプロセス内で Step の実行を試みます。Worker が API と同じプロセスで実行される場合は動作しますが、Worker が完全な Mastra Runtime にアクセスできない分離型デプロイでは失敗します。
スケーリングスケーリングへの直接リンク
Orchestration Worker とバックグラウンドタスク Worker は安全に水平スケーリングできます。PubSub Consumer Group がインスタンス間でイベントを分散するため、各イベントは一度だけ処理されます。
- Docker Compose
- Kubernetes
docker compose up -d --scale orchestration-worker=3
docker compose up -d --scale background-task-worker=2
kubectl scale deployment/orchestration-worker -n mastra-workers --replicas=3
kubectl scale deployment/background-task-worker -n mastra-workers --replicas=2
自動スケーリングするには、HorizontalPodAutoscaler を追加します。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: orchestration-worker
namespace: mastra-workers
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: orchestration-worker
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
CPU ベースの自動スケーリングには、Cluster で metrics-server を実行する必要があります。GKE、EKS、AKS などのマネージド Cluster にはデフォルトで含まれています。
API も Load Balancer の背後で水平スケーリングできます。
Scheduler Worker はスケーリングしないでください。 インスタンスを 1 つだけ実行します。複数の Scheduler が同じストレージを Poll すると、同じ Schedule に対して重複したイベントが発生します。
Crash RecoveryCrash Recoveryへの直接リンク
分散 PubSub Backend が未確認のイベントを永続化するため、Worker は Crash から復旧できます。
- Orchestration Worker:保留中のイベントは PubSub Backend に残ります。Worker を再起動すると、中断した場所から処理を再開します。
- Scheduler Worker:イベントが完全に失われることはありません。再起動時に Scheduler は、中断した場所ではなく現在時刻から次の実行時刻を計算します。
- Step 実行中の API:Orchestration Worker の HTTP リクエストが失敗します。イベントは Nack され、次の試行で再配信されます。
Step の実行中に API が Crash した場合(Sleep の途中など)、その Step の作業は失われます。Workflow の Run は running 状態のまま停止することがあります。現時点では、この状況に対する Timeout ベースの自動復旧はありません。
関連項目関連項目への直接リンク
- Worker:Worker の概要と使用するタイミング
- Worker 認証:Worker から API への通信を保護する
- Worker リファレンス:すべての Worker タイプの設定詳細
- CLI リファレンス:
mastra worker buildとmastra worker start - PubSub:イベント配信 Backend
- Mastra サーバーをデプロイする:ビルド出力とサーバー設定
- Mastra を Kubernetes にデプロイする:Durable Agent を使用した複数 Pod デプロイ