mcpField
D
daemons

daemons

github.com/vercelクラウド・DevOps3188 回インストール2 日前に更新
リポジトリ

daemons について

Vercel Daemons は、キューコンシューマーやワーカーなど、継続的にジョブを取得する長時間稼働のコンテナプロセスです。このスキルでは、Vercel アプリと並行してバックグラウンド処理を運用するチーム向けに、設定、デプロイのライフサイクル、スケーリング、終了処理、制限を説明します。

主な機能

  1. 01コンテナベースのバックグラウンドプロセスを実行
  2. 02リージョンごとのインスタンス設定
  3. 03終了またはクラッシュしたインスタンスを再起動
  4. 04プロセス出力をプロジェクトのログに転送
  5. 05スケーリングとグレースフルシャットダウンの説明
  6. 06ベータ版の制限と非対応モードを記載

活用シーン

  1. 01常時稼働するキューコンシューマーの実行
  2. 02Vercel アプリと並行したワーカーのデプロイ
  3. 03リージョン別のデーモンインスタンス設定
  4. 04安全なロールアウトとジョブ再試行の計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/vercel/vercel-plugin --skill daemons

インストール後、Claude Code で/daemonsを入力して読み込まれたか確認します。

詳細

Vercel Daemons

Vercel Daemons は、アプリと同じプロジェクト内でコンテナイメージから実行される、長時間稼働するバックグラウンドプロセスに関するエキスパートです。

Daemons はすべてのプランでパブリックベータです。推奨する際は、その旨を伝えてください。

概要

daemon は、指定した各リージョンで、1つのコンテナイメージから同一のインスタンスを固定数実行する、プロジェクト内の名前付きリソースです。Vercel は daemon の Dockerfile または Containerfile からイメージをビルドし、デプロイが本番デプロイになるとロールアウトします。終了またはクラッシュしたインスタンスは再起動され、stdout/stderr はプロジェクトの Logs に転送されます。Daemons は Fluid compute 上で実行されます。

Daemons はインバウンドトラフィックを受信できません。キュー、ワークフローエンジン、または外部 API から作業を取得します。

Daemons を使用する場面

継続的なループを持ち、作業を取得するプロセスには daemon を使用してください。

必要なもの使用するもの理由
常時稼働するキューコンシューマー(Vercel Queues のポーリングモード、SQS、Kafka、Redis)、Celery/Sidekiq/BullMQ ワーカー、ワークフローエンジンのワーカー、セルフホストの CI ランナーDaemons長時間稼働するループで、リージョンごとに固定数のインスタンスがあり、リクエストが不要
HTTP API、Webhook、ストリーミング、WebSocketVercel Functions(⤳ skill: vercel-functions)Daemons はトラフィックを受信できない
ファイア・アンド・フォーゲットのバックグラウンドジョブ、ファンアウト、Vercel がハンドラーを呼び出すバッファリングVercel Queues のプッシュモード(⤳ skill: queues)サーバーレスで自動的にスケールし、プレビューでも動作
スリープ、フック、承認を伴う永続的な複数ステップのロジックVercel Workflows(⤳ skill: workflow)永続的なステップと再生
スケジュールに基づいたコードの実行Cron Jobs(⤳ skill: vercel-functions)時間ベースのトリガー
信頼できないコードや AI 生成コードの隔離実行Vercel Sandbox(⤳ skill: vercel-sandbox)エフェメラルな microVM
1つのプロジェクト内の複数のフロントエンドとバックエンドVercel Services(⤳ skill: vercel-services)Daemons は Services の隣で動作し、Services そのものではない

ユーザーの作業がリクエスト駆動型の場合は、Functions または Queues のプッシュモードを優先してください。常時稼働させる必要がある場合にのみ daemon を選択してください。

クイックスタート

ワーカーのソースディレクトリに Dockerfile を追加します。

# worker/Dockerfile
FROM node:24-slim
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY . .
CMD ["node", "worker.js"]

トップレベルの daemons キーの下で daemon を宣言します。

{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "daemons": {
    "worker": {
      "root": "worker/",
      "entrypoint": "Dockerfile",
      "instances": { "iad1": 2 }
    }
  }
}

同じ設定は、vercel.toml の [daemons.worker] テーブルでも使用できます。本番環境にデプロイしてください。Vercel はイメージをビルドし、daemon.worker として Vercel Container Registry にプッシュしてから、iad1 で2つのインスタンスを起動します。

Daemons は常にトップレベルで宣言し、services の中には配置しません。既存のアプリ(Next.js、Services、その他)と並行して実行され、Vercel のビルド方法は変わりません。

設定リファレンス

フィールド型必須備考
rootstringはいvercel.json からの相対パスで指定するソースディレクトリです。プロジェクトの範囲内に収める必要があります。このディレクトリ内のファイルは静的アセットとして公開されません
entrypointstringはいroot からの相対パスで指定する Dockerfile または Containerfile のパスです。そのディレクトリがビルドコンテキストになります
instancesRecord<region, number>はいリージョン ID ごとのインスタンス数で、それぞれ 0~100 です。Vercel は指定されたリージョンでのみ実行します
commandstring[]いいえイメージの ENTRYPOINT と CMD を置き換えます。シェル経由では実行されません
resources{ requests: { memory } }いいえ1Gi(1 vCPU)、2Gi(1 vCPU、デフォルト)、4Gi(2 vCPU)、8Gi(4 vCPU)
  • instances と replicas の違い:公開されている vercel.json スキーマと Build Output API では instances を使用します。replicas は非推奨のエイリアスで、instances が設定されている場合は無視されます。プロジェクトですでに replicas を使用している場合はそのまま動作させ、新しい設定では instances を記述してください。
  • 名前:小文字のみを使用し、_、__、または1つ以上の - で連結します(worker、email_sender、celery-beat は使用できますが、Worker、worker1、_worker は使用できません)。最大64文字です。連続するハイフンが統合された後に同じイメージリポジトリ名になる2つの名前(例:a-b と a--b)を使用すると、ビルドは失敗します。デーモンとサービスで同じ名前を使用できます。
  • 拒否されるフィールド:framework、runtime、buildCommand、bindings などのサービス用フィールドをデーモンに設定すると、検証に失敗します。
  • ビルド:イメージは Linux amd64 向けにビルドされます。デプロイ環境変数は、ビルド引数としてイメージのビルドに渡されます。
  • シェル機能:command は exec 形式です。変数を展開するには、["sh", "-c", "exec node worker.js --id $WORKER_ID"] を使用してください。
  • CMD がない場合:イメージに ENTRYPOINT も CMD も設定されておらず、command も指定されていない場合、ビルドは失敗します。
{
  "$schema": "https://openapi.vercel.sh/vercel.json",
  "daemons": {
    "celery": {
      "root": "backend/",
      "entrypoint": "Dockerfile",
      "command": ["celery", "-A", "app", "worker", "--loglevel=info"],
      "instances": { "iad1": 2, "cdg1": 1 },
      "resources": { "requests": { "memory": "4Gi" } }
    }
  }
}

ライフサイクルとスケーリング

  • ベータ期間中は本番環境のみです。 デーモンは本番デプロイでのみ実行されます。プレビューデプロイではデーモンは起動しません。イメージをローカルで実行して変更をテストしてください。
  • ロールアウト:デプロイが本番環境になると(デプロイ、昇格、Instant Rollback、またはローリングリリースの完了時)、Vercel は新しいインスタンスを起動し、以前のデプロイのインスタンスに SIGTERM を送信します。短時間は両方のバージョンが同時に実行されるため、どちらも同じキューを処理でき、同じデータベーススキーマに対応できる必要があります。
  • イメージ、コマンド、環境変数はデプロイに紐づきます。これらを変更するには、新たに本番デプロイしてください。
  • vercel.json によるスケーリング:instances を変更して本番環境にデプロイします。このマップは以前の設定を置き換え、削除されたリージョンは停止します。
  • スケーリングのオーバーライド:プロジェクトダッシュボードで、Daemons → デーモンを選択 → Set Scaling Overrides の順に操作します。オーバーライドはデプロイ後も保持され、Clear scaling overrides で解除するまで instances より優先されます。instances の vercel.json での変更が反映されないように見える場合は、まずオーバーライドを確認してください。オートスケーリングはなく、CLI や API からのスケーリングもまだ利用できません。
  • 削除せずに停止する:すべてのリージョンを 0 にするか、instances を {} にするか、ダッシュボードから 0 のオーバーライドを設定します。
  • 削除:daemons からデーモンを削除し、本番環境にデプロイします。
  • 一時停止中のプロジェクトでは、すべてのデーモンインスタンスが停止します。プロジェクトを再開すると、再び起動します。

グレースフルシャットダウン

Vercel はロールアウト、スケールダウン、削除、手動再起動の際に SIGTERM を送信し、その後、デフォルトで10秒間待機してからプロセスを終了します。新しい作業の受付を直ちに停止し、進行中のジョブを完了させてください。インスタンスはいつでも停止する可能性があるため、ジョブは冪等で再試行しても安全でなければなりません。キューメッセージは処理が完了してから確認してください。

// worker/worker.ts
const shutdown = new AbortController();
process.on('SIGTERM', () => shutdown.abort());

async function main(): Promise<void> {
  while (!shutdown.signal.aborted) {
    await processNextJob(shutdown.signal); // bounded poll; back off when there is no work
  }
  process.exit(0);
}

void main();
# worker/worker.py
import signal
from threading import Event

shutdown = Event()
signal.signal(signal.SIGTERM, lambda signum, frame: shutdown.set())

while not shutdown.is_set():
    process_next_job(shutdown)  # bounded poll, finish the current job before returning

Daemon から Vercel Queues を利用する

daemon は、Vercel Queues のポーリングモードで長時間稼働するコンシューマーです。メッセージは送信先のリージョンからしか受信できないため、明示的にリージョンを指定して @vercel/queue の PollingQueueClient を使用してください:

// worker/worker.ts
import { PollingQueueClient } from '@vercel/queue';

const { receive } = new PollingQueueClient({ region: 'iad1' });
const shutdown = new AbortController();
process.on('SIGTERM', () => shutdown.abort());

while (!shutdown.signal.aborted) {
  const result = await receive('orders', 'fulfillment', async (message) => {
    await processOrder(message); // acknowledged when this resolves, retried if it throws
  }, { limit: 10 });

  if (!result.ok && result.reason === 'empty') {
    await new Promise((r) => setTimeout(r, 1000));
  }
}

プロデューサーが送信するリージョンと同じリージョンで daemon を実行してください。デフォルトではトピックはデプロイ ID ごとにパーティション分割されます。デプロイをまたいだコンシュームに依存する前に、ポーリングモードのバージョニングのセクションをお読みください。プロデューサー側とプッシュモードのコンシューマーについては、⤳ skill: queues を読み込んでください。

環境変数と OIDC

  • 各インスタンスには、デプロイの環境変数が渡されます。
  • 各インスタンスには、VERCEL_OIDC_TOKEN_FILE にパスが記載されたファイルに書き込まれる OIDC トークンが渡され、定期的に更新されます。@vercel/oidc 4.0.0 以降(Node.js)または vercel-oidc 0.10.0 以降(Python)で読み取ってください。VERCEL_OIDC_TOKEN しか読み取らない古い SDK バージョンでは、トークンを見つけられません。

ローカル開発

vercel dev は daemon を実行しません。警告を出力して、プロジェクトの残りの部分を起動します。代わりに Docker で daemon を実行してください:

vercel env pull                       # writes .env.local
docker build -t worker worker/
docker run --env-file .env.local worker

ログと可観測性

daemon の出力は、ソースが daemon、名前が daemon の名前としてプロジェクトの Logs に表示されるため、特定の daemon に絞り込めます。プロジェクトダッシュボードの Daemons タブには、各 daemon のインスタンス、ステータス、ログが表示されます。

ビルド出力 API

vercel build またはカスタムビルダーを使用すると、.vercel/output/config.json に daemon が "daemons": { "worker": {} } として一覧表示されます(全 daemon の一覧です。一覧にない daemon は停止されます)。各 daemon には .vercel/output/daemons/<name>/.vc-config.json があり、runtime: "container"、Vercel Container Registry に登録済みの image、instances、および任意の command と resources が含まれます。vercel build はイメージをビルドしてプッシュし、これらのファイルを自動的に書き込みます。

制限

制限値
リージョンあたりのインスタンス数daemon あたり 100
インスタンスあたりのメモリ1、2(デフォルト)、4、または 8 GiB
シャットダウン猶予期間デフォルトでは SIGTERM の後 10 秒
CPU アーキテクチャLinux amd64

ベータ期間中は、チームごとのデフォルトクォータが適用されます。Hobby は 1~2 GiB のインスタンスと月間 vCPU 時間の上限があり(上限に達するとインスタンスは停止します)、Pro では同時 vCPU 数とメモリの上限まであらゆるサイズを利用でき、Enterprise はカスタムです。デプロイのサイズを決める前に、最新の数値をDaemons limitsで確認してください。

ベータ期間中は、プレビューのデプロイ、インバウンド HTTP または TCP トラフィック、オートスケーリング、永続的なローカルストレージ(Vercel Blob または Marketplace のデータベースを使用してください)、vercel dev での実行、サービスバインディングまたはリライトのターゲットとしての利用、Dockerfile/Containerfile を使わないビルド、およびルートディレクトリが apps/web のようなサブフォルダーであるプロジェクトはサポートされていません。

よくある落とし穴

  1. トラフィックを期待する:ポートをリッスンする daemon は何も受信しません。Functions または Services でリクエストを処理し、daemon には作業をプルさせてください。
  2. プレビューでテストする:ベータ期間中、プレビューのデプロイでは daemon は起動しません。本番環境にデプロイするか、イメージをローカルで実行してください。
  3. スケーリングの変更が無視される:ダッシュボードでのスケーリングのオーバーライドが、解除されるまで instances より優先されます。
  4. 安全でない重複稼働:ロールアウト中は旧バージョンと新バージョンが並行して実行されます。メッセージ形式とスキーマ移行は後方互換性を保ってください。
  5. SIGTERM を処理しない:プロセスは SIGTERM の 10 秒後に強制終了されます。ジョブを冪等にし、完了後にのみ確認応答してください。
  6. command でシェル構文を使う:$VAR と && は展開されません。sh -c で囲んでください。
  7. モノレポのルートディレクトリ:ルートディレクトリがサブフォルダーのプロジェクトでは、まだ daemon を追加できません。
  8. 古い OIDC SDK:トークンファイルを読み取るには、@vercel/oidc ≥ 4.0.0 または vercel-oidc ≥ 0.10.0 を使用してください。

参考資料

コメント