ひとことで言うと
Cloudflare → Workers & Pages → プロジェクト → Deployments → Failedのビルド → Build log
→ 右上の「Download logs」でテキスト保存 → VSCodeでCtrl+FしてERRORを検索
ビルドログを目視でスクロールするのは1000行超えで破綻する。Download → テキスト検索が圧倒的に速かった。
やりたかったこと
AstroサイトをCloudflare Pagesにデプロイしたらビルドが失敗した。Deploymentsタブに「Failed」と表示されているが、何が原因なのかわからなかった。「View build logs」を押したら大量のログが出てきて、どこを見ればいいかわからないまま5分以上スクロールし続けた。
✘ [ERROR] Could not resolve "@astrojs/sitemap"
というエラーが出ていたが、ローカルでは正常にビルドが通っていた。「ローカルで動くのになぜCloudflareで失敗するのか」という状況が何度も続いて、毎回ビルドログの読み方に迷っていた。
環境
- Windows 11
- Node.js 20.11.0
- npm 10.2.4
- Astro 5.2.3
- Cloudflare Pages(Freeプラン)
試したこと・うまくいかなかったこと
ビルドログをスクロールしながらエラーを探した → 1000行で破綻
最初、ビルドログのページを開いてからスクロールバーを手で動かしながらエラーを探していた。ログが1000行以上あって、どこにエラーがあるかわからないまま何分もスクロールしていた。ブラウザのCtrl+Fで「Error」を検索しようとしたが、Cloudflareのビルドログビューアはリアルタイムで行が追加される仕組みのためか、ブラウザの検索機能が正常に機能しなかった。
npm warn deprecated をエラーの原因だと思って30分調べた
npm warn deprecated が大量に出ていて、最初はそのWARNINGが原因だと思ってパッケージを調べ始めた。
npm warn deprecated react@17.0.2: This version has vulnerabilities. Please update.
npm warn deprecated mkdirp@0.5.6: Legacy versions of mkdirp are no longer supported.
30分ほど調べてから「WARNINGはビルド失敗に直接関係ない」とわかった。ERRORとWARNINGの違いを意識せずにいたせいで、見るべきものを見逃していた。
Failedのビルドから「Build log」タブへの入り方がわからなかった
「Failed」の文字をクリックしてもリンクになっていなかった。ビルドのタイムスタンプかビルド番号のリンクをクリックすると詳細ページに入れるのに気づくまで時間がかかった。さらに詳細ページを開いた後に「Build log」タブが別に存在していて、最初は「Deployments」タブを開いたままエラーを探していた。
解決策
ビルドログの開き方
- Cloudflareダッシュボード → 「Workers & Pages」
- 対象プロジェクト → 「Deployments」タブ
- 「Failed」になっているビルドのタイムスタンプかビルドIDのリンクをクリック
- ビルド詳細ページの「Build log」タブを開く
「Failed」の文字はリンクになっていない場合がある。ビルドのタイムスタンプかビルド番号のリンクをクリックすると詳細ページに入れる。
効率的なエラーの見つけ方
「Download logs」でテキストとして保存してから検索するのが圧倒的に速かった。
ビルドログページ右上の「Download logs」ボタンを押すとテキストファイルがダウンロードされる。VSCodeで開いてCtrl+FでERRORを検索する。
# ダウンロードしたログをVSCodeで検索
Error: Cannot find module
✘ [ERROR]
Build failed
ログは大きく3フェーズに分かれている。エラーがどのフェーズで出ているかで原因が変わる。
Installing dependencies... ← ここのエラー = package.jsonの依存問題
Building Astro site... ← ここのエラー = ビルド設定やコードの問題
→ rendering pages... ← ここのエラー = ページコンテンツの問題
依存関係のエラーはログの前半、レンダリングエラーはログの後半に出る。「ログの最後を見ればいい」という思い込みで前半を読み飛ばすと本当のエラーを見逃す。
成功時のログの流れ
11:23:04.123 Cloning repository...
11:23:06.204 Installing project dependencies
11:24:02.891 npm install completed in 56.7s
11:24:03.012 Building with Astro
11:24:04.445 ✓ 26 pages built in 3.21s
11:24:04.446 Build complete
11:24:05.001 Uploading...
11:24:11.232 Success: Your site was deployed
このフローで最後に「Success」が出れば正常完了。
よくあるエラーと対処法
依存パッケージが見つからない
✘ [ERROR] Could not resolve "@astrojs/sitemap"
→ @astrojs/sitemap が devDependencies に入っている。本番ビルドでは devDependencies はインストールされない。npm install @astrojs/sitemap --save で dependencies に移す。
# 移し直すコマンド
npm uninstall @astrojs/sitemap
npm install @astrojs/sitemap --save
Node.jsバージョン不一致によるTypeScriptエラー
error TS2339: Property 'xxx' does not exist on type 'ImportMeta'
→ CloudflareのデフォルトNode.jsバージョンがローカルより古い。Settings → Environment variables で NODE_VERSION=20 を追加して再デプロイする。
Astro 5でAPIが変わっていた
Astro.glob is not a function
→ Astro 5以降で Astro.glob() が廃止された。import.meta.glob() に書き換える。
// Astro 4まで
const posts = await Astro.glob('./posts/*.md');
// Astro 5以降
const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));
サイトmap設定のビルドエラー
[@astrojs/sitemap] No `site` option is set in your Astro config.
→ astro.config.mjs に site: 'https://yourdomain.com' を追加する。ローカルのdevモードではこのエラーが出ないのにビルド時だけ出る。
ビルド時間超過
Build exceeded the time limit of 20 minutes
→ ビルド時間超過。sharp による画像最適化が重い場合に起きやすい。画像の枚数が多いサイトでは @astrojs/image の設定を見直す。
記事frontmatterの必須フィールド不足
✘ [ERROR] rendering /posts/xxx...
Error: Cannot read properties of undefined (reading 'title')
→ 記事のfrontmatterに必須プロパティが抜けているか、レイアウト側で undefined チェックをしていない。ローカルで npm run build を実行して同じエラーが出るか確認する。
ローカルで本番ビルドを再現する
Cloudflareでしか出ないエラーを減らすには、ローカルでも本番と同じ条件でビルドする。
# devDependenciesを除いてinstallしてビルド
rm -rf node_modules
npm install --omit=dev
npm run build
これで本番環境と同じ条件でビルドが通るか事前確認できた。
古いコミットがデプロイされているとき
ビルドは成功しているのに古い内容が表示される場合、空コミットで強制的にデプロイをトリガーする。
git commit --allow-empty -m "force deploy"
git push
ハマったポイント
npm warn deprecatedが大量に出ていてWARNINGを原因だと思って調べ続けた。WARNINGはビルド失敗に直接関係しない。Error:や✘ [ERROR]が出ている行だけを見ればよく、WARNINGは無視していい。ERRORとWARNINGを混同したまま30分溶かした- ブラウザのビルドログビューアでスクロールしながらエラーを探すのは1000行超えのログでは現実的でない。「Download logs」でテキスト保存してVSCodeで
ERRORを全文検索するのが圧倒的に速かった。この手順に気づいてからビルドエラーの解決時間が10分の1になった - ローカルで
npm run buildが通るのにCloudflareで失敗するのは、ほぼNode.jsのバージョン差異かdevDependenciesの問題。この2点を最初に確認するだけで大半のケースが解決できた。devDependenciesに入れたパッケージはClooudflareの本番ビルドでインストールされないという事実は最初に知っておきたかった - ログの依存インストールフェーズのエラーは前半に出る。「最後にエラーがある」と思い込んでログの後半だけ見ていたら、前半で起きているnpm installの失敗を見落とした。全文検索で
ERRORを探す方法に切り替えてから前後の区別が不要になった - Deploymentsタブで「Failed」のビルドをクリックしてから「Build log」タブを探す必要がある。「View build logs」というリンクやボタンが見当たらないときは、ビルドのタイムスタンプのリンクをクリックしてから「Build log」タブに入る手順で見つかった。UIが直感的でないので初見では迷う
よくある質問
Q: ビルドログはどのくらいの期間保存されますか? Cloudflareのビルドログは通常90日間保存される。古いビルドのログも確認できるが、削除されている場合もある。重要なエラーログは「Download logs」でローカルに保存しておくと安心だった。
Q: ビルドがどこで止まっているか素早く確認する方法は? ダウンロードしたログの最終行を見ると、ビルドがどのフェーズで止まったかがわかる。「Installing dependencies…」で止まっていれば依存の問題、「Building with Astro」で止まっていればコードの問題。
Q: ローカルのビルドとCloudflareのビルドを一致させるには?
rm -rf node_modules && npm install --omit=dev && npm run build をローカルで実行して事前確認する。これで devDependencies の問題が発見できる。Node.jsバージョンの差異は NODE_VERSION=20 を環境変数に追加することで揃えられる。
Q: ビルドエラーのメール通知を受け取れますか? 設定できる。Cloudflareダッシュボード → 「Workers & Pages」 → プロジェクト → 「Settings」 → 「Notifications」でビルド失敗のメール通知を追加できる。pushするたびにDeploymentsタブを確認しなくてよくなった。
デプロイが全く来ない場合はビルドエラーではなくGitHubとの接続切れが原因のこともある。その場合はCloudflare PagesがGitHubと切断された時の対処法を確認してほしい。
関連記事
- Cloudflare PagesがGitHubと切断された時の対処法
- Cloudflare PagesのGitHub自動デプロイが動かない時の対処法
- AstroをCloudflare Pagesにデプロイする手順
- Astroでrobots.txtとsitemapを自動生成する方法
ドメイン取得はこちら
Cloudflareと組み合わせるドメインの取得に。