npm run build 相当が走る
GitHub の Webhook という仕組みを使っているらしいです。
リポジトリに何か起きたとき(push、PR、merge…)に、GitHub が 事前に登録された URL に HTTP リクエストを投げてくれる機能。Vercel は連携時にこの Webhook URL を登録しているので、push の瞬間に通知が飛ぶ仕組み。
…つまり、Vercel が GitHub を監視してるのではなく、GitHub が Vercel に「変更あったよ!」って教えてあげてる側でした。
# 私たちが触るのはここまで $ git push origin main ↓ [ GitHub ] ↓ webhook (HTTP POST) [ Vercel ] ↓ ビルドキューに登録 ↓ ビルド開始
Vercel が 使い捨てのビルドコンテナ を一個立ち上げて、その中でビルドします。
イメージとしては「クリーンな Linux サーバーが毎回新しく用意されて、git clone してビルドして、終わったら消える」感じ。だから誰がビルドしても結果が同じになる(再現性)。
ローカルだと「私の環境では動く」になりがちだけど、毎回ゼロから作るのでその罠が起きにくい設計らしいです。
[ ビルドコンテナ ]
┌─────────────────────┐
│ 1. git clone │
│ 2. npm install │
│ 3. npm run build │
│ 4. 成果物を取り出す │
│ 5. コンテナ破棄 │
└─────────────────────┘
↓
成果物 (静的ファイル + Function)
ファイルの種類によって 置き場所が違う んです。
「全部 CDN に置けば速い」じゃなくて、適材適所で配り分けてるんだなと。
ビルド成果物
│
┌────────┼────────┐
↓ ↓ ↓
[ 静的 ] [ API ] [ Middleware ]
HTML Serverless Edge
CSS Function Function
画像 ↓ ↓
↓ 米国DC等 世界中のPoP
世界中
のCDN
※ 種類によって配り先が違う
Vercel は新しいデプロイを 別の URL で完成させてから、最後に切り替える ようになってます。
イメージとしては「新しいお店を裏でこっそり完成させて、看板(DNS)だけ最後にスッと差し替える」感じ。
なので、デプロイ中もユーザーは 古いバージョンを問題なく見られる。切り替えは一瞬。失敗したらすぐ前の URL に戻せる(即ロールバック)のもこの仕組みのおかげ。
デプロイ中: mysite.com ──→ deploy-v1 (稼働中) deploy-v2 (裏で準備中) 準備完了の瞬間: mysite.com ──→ deploy-v2 (切替) deploy-v1 (残ってる) ロールバック時: mysite.com ──→ deploy-v1 (戻すだけ) deploy-v2
Vercel は世界中に PoP (Points of Presence) という拠点を持っていて、ユーザーは 自動的に最寄りの拠点 に繋がります。
「同じ URL を打っても、東京の人は東京の拠点に、NY の人は NY の拠点に繋がる」というのが裏側で起きてること。物理的な距離が短い分、表示が速い。
この「自動で最寄りに振り分ける」仕組みが Anycast というルーティング技術なんですが、これは Vol.2 で詳しくやります。
同じ mysite.com にアクセス
[Tokyo User] [NY User]
↓ ↓
PoP Tokyo PoP New York
(数 ms) (数 ms)
↓ ↓
キャッシュHIT キャッシュHIT
↓ ↓
表示 表示
※ どちらも同じURL、自動で最寄りへ
そういう「毎回違う結果になるやつ」は、Serverless Function として登録されます。
リクエストが来た瞬間に、関数が起動して、処理して、レスポンスを返す。使い終わったら消える。サーバーをずっと起動しっぱなしにしないので、コストが安い…らしいです。
ただし起動に少し時間がかかる(Cold Start問題)など、トレードオフも色々あるみたい。これも Vol.2 で。
普通のサーバー: [Server]──常時起動──┐ 高コスト ├ Request 即レスポンス ┘ Serverless: Request → [ 関数を起動 ] → レスポンス ↓ 使い終わったら消える + 使った分だけ課金 + 自動でスケールする - Cold Start