Claude Code × Vercel デプロイ自動化 — git push から本番反映まで AI に任せる
Claude Code と Vercel CLI を組み合わせて、フロントエンドのデプロイフローをAIが自律実行する実践ガイド。Vercel CLI直接実行・GitHub Actions 3層構成・Preview Deployの自動レビュー・環境変数管理・ロールバック設計まで網羅。
エンジニアのゆとです。
「git pushしたら自動でデプロイされる」——Vercelを使ったことがある人には当たり前の話だ。
ただ、実際の現場はそんなに単純じゃない。pushの前にビルドが通るか確認したい。Preview Deployのレビューは手動でURLを開いて確認している。デプロイが失敗したとき原因を調べる作業がある。環境変数の設定漏れに気づくのはデプロイ後だったりする。
このあたりの「手動でやってる作業」に Claude Code を差し込むと、フロントエンドのデプロイフローがかなり変わる。
この記事では、CC × Vercel の具体的な実装パターンを全部公開する。VercelはNext.js・SvelteKit・Astroなどのフロントエンドフレームワーク全般に対応しているので、フレームワーク問わず参考になるはず。
なぜ CC × Vercel なのか
Vercelの自動デプロイは優秀だが、「CCが入ることで何が変わるか」を先に整理しておく。
Vercelが担う領域とCCが担う領域は明確に分かれる。
Vercelが得意なのはビルド実行・CDN配信・Preview URL生成・環境変数管理のUI。これは既存の仕組みをそのまま使う。
CCが担う領域はその前後だ。pushする前のビルドチェック・差分の自動レビュー・Preview Deployの変更点確認・デプロイ失敗時の原因分析・rollback判断のサポート。
「デプロイ自体をCCにやらせる」というよりは、「デプロイの前後の判断とチェックをCCが担う」イメージが近い。
Vercel CLI のセットアップ
まずVercel CLIを入れる。
npm i -g vercel
プロジェクトとの紐付けは vercel link で行う。既存プロジェクトがVercel上にある場合はそれを選択し、新規の場合はその場で作成できる。
cd /path/to/project
vercel link
実行後、.vercel/project.json が生成される。このファイルにプロジェクトIDとorgIDが入る。CCがVercel CLIを実行する際にこのファイルを参照するので、リポジトリに含めておく(secretsは入っていないので問題ない)。
認証トークンの設定は .env.local ではなくシェル環境変数かCIのSecretsに入れる。
# ローカル: ~/.zshrc or ~/.zshenv
export VERCEL_TOKEN="<your-token>"
# CI: GitHub Actions Secrets に VERCEL_TOKEN として登録
トークンはVercelのダッシュボード → Settings → Tokens から発行できる。スコープはプロジェクト単位にしておくと漏洩リスクを限定できる。
CC ワークフロー実装
パターン1: CC が Vercel CLI を直接実行する
ローカル開発での使い方。CCをインタラクティブに使いながら、デプロイコマンドもCCに実行させる構成だ。
CLAUDE.md にVercel CLIの使用を許可しておく。
# CLAUDE.md
## Allowed commands
- vercel deploy (preview deploy のみ)
- vercel --prod (本番デプロイ。要確認)
- vercel env (環境変数確認のみ。書き込みは確認後)
- vercel rollback (確認後に実行)
CCへの指示例:
現在のブランチをVercel Previewにデプロイして、
ビルドログを確認してエラーがあれば原因を教えて
CCはこれを受けて vercel deploy を実行し、ビルドログを読み、エラーがあれば分析する。ローカルからPreviewを出す用途に特に向いている。本番デプロイ(vercel --prod)はCCに確認を求めるよう CLAUDE.md に明示しておくほうが安全だ。
CCが実行するコマンドの実態はこれだけだが、「ログを読んで原因を言語化する」部分がCCの本領になる。
パターン2: GitHub Actions × CC × Vercel の3層構成
本番向けの構成。PRのレビュー・Previewデプロイ・本番デプロイを自動化する。
ローカル (CC) → GitHub (PR) → Actions (CC + Vercel CLI) → Vercel
ワークフロー全体像:
# .github/workflows/vercel-preview.yml
name: Vercel Preview Deploy + CC Review
on:
pull_request:
branches: [main]
jobs:
preview-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Install Vercel CLI
run: npm install -g vercel
- name: Deploy to Preview
id: deploy
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
run: |
DEPLOY_URL=$(vercel deploy --token=$VERCEL_TOKEN 2>&1 | tail -1)
echo "url=$DEPLOY_URL" >> $GITHUB_OUTPUT
echo "Preview URL: $DEPLOY_URL"
- name: CC Diff Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# mainからのdiffを取得
git diff origin/main...HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx' '*.astro' \
> /tmp/diff.txt
# CCに差分レビューを依頼
python3 << 'EOF'
import anthropic, pathlib, os
diff = pathlib.Path('/tmp/diff.txt').read_text()
preview_url = "${{ steps.deploy.outputs.url }}"
client = anthropic.Anthropic()
msg = client.messages.create(
model="claude-opus-4-5",
max_tokens=2048,
messages=[{
"role": "user",
"content": f"""以下のPR差分をレビューしてください。
Preview URL: {preview_url}
確認項目:
1. バグリスクがある変更はないか
2. 型エラーにつながりそうな変更はないか
3. パフォーマンスに影響しそうな変更はないか
4. 環境変数の追加・変更があれば明示
差分:
```
{diff[:8000]}
```
"""
}]
)
print(msg.content[0].text)
EOF
- name: Comment PR
uses: actions/github-script@v7
with:
script: |
const deployUrl = "${{ steps.deploy.outputs.url }}";
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Preview Deploy\n\n${deployUrl}\n\n---\n\nCCによる差分レビューは Actions ログを確認してください。`
})
本番デプロイは別ワークフローで管理する。mainへのmerge時に発火させる。
# .github/workflows/vercel-production.yml
name: Vercel Production Deploy
on:
push:
branches: [main]
jobs:
production-deploy:
runs-on: ubuntu-latest
environment: production # GitHub Environmentsで承認フローを設定可能
steps:
- uses: actions/checkout@v4
- name: Install Vercel CLI
run: npm install -g vercel
- name: Deploy to Production
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
run: vercel deploy --prod --token=$VERCEL_TOKEN
environment: production を設定しておくと、GitHub Environmentsの承認フローが使える。mainにmergeされても、designatedなレビュアーが承認するまで本番デプロイが走らない。チームで使う場合は入れておくといい。
パターン3: Preview Deploy の自動レビュー
Preview URLが発行されたら、CCがそのページを巡回してチェックする構成。Playwright(または fetch)でページを叩いてエラーを検知する。
# scripts/check_preview.py
import anthropic
import subprocess
import sys
import json
def check_preview(preview_url: str) -> dict:
"""Preview URLの基本チェックを実行してCCにレポートさせる"""
# 基本的なHTTPチェック
result = subprocess.run(
['curl', '-sI', preview_url],
capture_output=True,
text=True,
timeout=30
)
headers = result.stdout
# コンソールエラーのチェック(簡易版: statusコードとheader確認)
status_line = headers.split('\n')[0] if headers else 'No response'
client = anthropic.Anthropic()
msg = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": f"""Preview Deploy のチェック結果を分析してください。
URL: {preview_url}
HTTPレスポンス:
{headers[:2000]}
確認してほしいこと:
- ステータスコードは正常か
- セキュリティヘッダー(X-Frame-Options、CSP等)は設定されているか
- キャッシュ設定は意図通りか
- 問題があれば具体的に指摘してください
"""
}]
)
return {
"url": preview_url,
"status": status_line,
"review": msg.content[0].text
}
if __name__ == "__main__":
url = sys.argv[1]
result = check_preview(url)
print(json.dumps(result, ensure_ascii=False, indent=2))
GitHub Actionsに組み込む場合は、deploy stepの後にこのスクリプトを呼ぶだけでいい。
環境変数管理
Vercelの環境変数管理は3層になっている。
.env.local(ローカル開発用、gitignore)- Vercel Dashboard(本番・Preview・Development環境ごとに設定)
- 1Password CLI(シークレットの根っこ)
この3層をどう整合させるかが実際のハマりポイントになる。
推奨構成:
1Password Vault
└── OPENAI_API_KEY
└── DATABASE_URL
└── etc...
↓ op inject
.env.local(ローカル)
↓ vercel env pull
.env.vercel(Vercelの値をローカルに引っ張る)
vercel env pull コマンドを使うと、Vercelに設定されている環境変数をローカルに .env.vercel として落とせる。ただしこのファイルはgitignoreに必ず入れる。
vercel env pull .env.vercel
1Password CLIを使う場合の op run との組み合わせ:
# Vercelの値でビルドしたい場合
op run --env-file=".env.vercel" -- npm run build
# ローカルのVault値でビルドしたい場合
op run --env-file=".env.local.template" -- npm run build
CCへの環境変数管理の委任はここまでで止めておくのが安全だ。「CCに vercel env add を実行させる」は避ける。環境変数の追加・削除はVercel Dashboardか手動の vercel env コマンドで行うほうが事故が少ない。
記事が見つかりません:
ドメイン設定の自動化
Vercel CLIでドメインの割り当ても操作できる。
# ドメインをプロジェクトに追加
vercel domains add yourdomain.com
# カスタムドメインをProductionにアサイン
vercel alias set <deploy-url> yourdomain.com
ただしDNSの変更(Aレコード・CNAMEの設定)は Vercel CLI では行えない。DNS変更はドメインレジストラ側の操作が必要だ。
CCにドメイン設定のチェックをさせるならこういう指示になる:
vercel domains inspect yourdomain.com を実行して、
DNS設定が正しく引いているか確認して
CCが vercel domains inspect の出力を読んで、DNS propagationの状態・SSL証明書の状態・正しいVercel IPに向いているかを確認してくれる。
失敗時のロールバック設計
Vercelのロールバックは vercel rollback コマンドで実行できる。特定のDeployment IDに戻すことも、直前のDeploymentに戻すことも両方できる。
# 直前のデプロイに戻す
vercel rollback
# 特定のDeployment IDに戻す
vercel rollback <deployment-id>
CCとの組み合わせでロールバック判断を自動化する構成:
# scripts/monitor_and_rollback.py
"""
デプロイ後に一定時間監視し、エラー率が閾値を超えたら
CCにロールバック可否を判断させる
"""
import anthropic
import subprocess
import time
import json
def get_deployment_info() -> dict:
result = subprocess.run(
['vercel', 'ls', '--json'],
capture_output=True, text=True
)
return json.loads(result.stdout)
def check_error_rate(deployment_url: str) -> float:
"""簡易エラー率チェック(本番ではVercel Analytics APIを使うこと)"""
result = subprocess.run(
['curl', '-sw', '%{http_code}', '-o', '/dev/null', deployment_url],
capture_output=True, text=True
)
status = result.stdout.strip()
return 1.0 if status.startswith('5') else 0.0
def should_rollback(error_rate: float, deployment_info: dict) -> bool:
client = anthropic.Anthropic()
msg = client.messages.create(
model="claude-opus-4-5",
max_tokens=512,
messages=[{
"role": "user",
"content": f"""デプロイ後の監視データを見てロールバックが必要か判断してください。
エラー率: {error_rate * 100:.1f}%
デプロイ情報: {json.dumps(deployment_info, ensure_ascii=False, indent=2)[:1000]}
ロールバックが必要な場合は 'ROLLBACK' と、不要な場合は 'CONTINUE' と
最初の単語で答えてください。理由も添えてください。
"""
}]
)
response = msg.content[0].text
return response.strip().startswith('ROLLBACK')
def main():
print("デプロイ後モニタリング開始(5分間)...")
deployments = get_deployment_info()
for i in range(5):
time.sleep(60)
error_rate = check_error_rate(deployments[0].get('url', ''))
print(f"{i+1}分経過: エラー率 {error_rate * 100:.1f}%")
if error_rate > 0.1: # 10%超でCCに判断させる
if should_rollback(error_rate, deployments[0]):
print("CCがロールバックを推奨。実行します...")
subprocess.run(['vercel', 'rollback'], check=True)
return
print("モニタリング完了。問題なし。")
if __name__ == '__main__':
main()
このスクリプトはあくまで判断のサポートだ。ロールバックを完全に自動化するかどうかは運用ポリシーによる。本番環境では subprocess.run(['vercel', 'rollback']) を実際に実行する前に人間の確認を挟むほうが安全なことが多い。
ハマりどころ
ビルドキャッシュの罠
Vercelのビルドキャッシュは便利だが、依存関係を変えたときに古いキャッシュが残って挙動がおかしくなることがある。特に node_modules のキャッシュが問題になりやすい。
# キャッシュをクリアして強制フルビルド
vercel deploy --force
CCにデバッグを頼むとき「キャッシュが原因かもしれない」という文脈を渡しておくと、--force を提案してくれることが多い。
環境変数の順序問題
Vercelは環境変数を以下の優先順位で適用する。
1. .env.local(最高優先度)
2. .env.development / .env.production
3. .env
Vercel Dashboardで設定した値は「Vercel環境の .env」として扱われる。ローカルの .env.local が存在すると上書きされるので、「ダッシュボードで設定したはずなのにローカルで反映されない」は大抵これが原因だ。
CCに調査させるなら:
vercel env ls コマンドで環境変数の一覧を出して、
Development/Preview/Production の3環境それぞれの設定状況を確認して
Edge Functions の制約
Vercel Edge FunctionsはNode.jsランタイムではなくV8ベースのランタイムで動く。これがビルド時に問題になるケースがある。
具体的にハマりやすいのは:
fsモジュールが使えない- Node.js固有のAPIが動かない
- バンドルサイズ上限(1MB)がある
- Cold start時間は短いが、実行時間上限(5〜30秒)がある
CCにEdge Functionsのコードレビューを頼む場合は「Edge Runtimeでの制約を考慮してレビューして」と明示するといい。CCはEdge Runtimeの制約を知っているので、問題のあるコードを指摘してくれる。
vercel deploy と vercel --prod の違い
vercel deploy はPreviewデプロイ、vercel --prod は本番デプロイ。GitHub Actions上でミスりやすいので、ワークフローのステップ名に明示しておくといい。
誤って本番にデプロイしてしまった場合は vercel rollback で戻せるが、それ以前にCI設定で本番デプロイ用のワークフローとPreview用ワークフローを完全に分けておくほうがリスクが低い。
まとめ
CC × Vercel のポイントを整理する。
CCが特に効果を発揮するのは「ビルドログの原因分析」「PR差分のレビュー」「デプロイ後の監視と判断サポート」の3つ。Vercelが自動でやってくれる部分(ビルド実行・CDN配信)はそのまま任せて、その前後の判断系タスクをCCに渡すのが現実的な構成だ。
「全部CCに任せる」よりも「CCが判断して人間が実行を承認する」ラインに落とすほうが、本番トラブルのリスクが下がる。特にロールバックは自動化しすぎると意図しない状態になることがあるので、最終トリガーは人間に残しておくことをすすめる。
GitHub ActionsのワークフローはYAMLを一本書けば動くので、まずはPreview Deploy時のCCレビューから始めるといい。コストも大してかからないし、PRレビューの質が上がる実感は早い段階で得られる。
記事が見つかりません: