【原因と対策】Cloudflare PagesでAstroのビルドが失敗する5大原因と解決手順!Nodeバージョン・環境変数の罠

自分のパソコン(ローカル環境)で npm run dev や npm run build を実行したときはエラーひとつ出ず完璧に動いていたのに、GitHubへプッシュしてCloudflare Pagesで自動デプロイが走った瞬間、「Failed: build command exited with code: 1」という真っ赤なエラーが出てビルドが失敗してしまう——これはAstro × microCMSでサイトを構築する個人開発者が必ず一度は通る最大の壁です。
さらに厄介なのは、Cloudflare Pagesのデプロイ画面を開くと数千行におよぶ英語のシステムログが並んでおり、「結局どの行が本当の原因なのか」が初見では非常に分かりにくい点にあります。
結論からお伝えすると、Cloudflare PagesにおけるAstroのビルド失敗は、9割以上が「ローカル環境とクラウド(Linux)環境の前提条件のズレ」から生じる以下5つの原因に集約されます。
- Node.jsのバージョン不一致: Cloudflare側のNodeバージョンが古く、最新Astroが要求する構文やパッケージが動かない
- 環境変数(
.env)の未登録: Git管理外であるMICROCMS_API_KEY等がCloudflare側に登録されておらず、API通信で落ちる - ファイルパスの大文字・小文字の不一致: WindowsやMacでは無視される
Header.astroとheader.astroの違いがLinux上でエラーになる package-lock.jsonの競合と依存関係エラー: ローカルと異なるバージョン解決が走り、npm clean-installでコケる- ビルド出力先(
dist)やSSRアダプター設定の不一致: Cloudflare Pages側のフレームワークプリセット設定がズレている
本記事では、数千行のビルドログから「わずか10秒でエラーの真因を特定するログの読み方」と、上記5大原因を確実に解消する具体的な手順をステップバイステップで徹底解説します。
なぜローカルで動くAstroがCloudflare Pagesのビルドで落ちるのか?
具体的な修正手順に入る前に、なぜ「自分のパソコンでは動くのに、Cloudflare Pagesではエラーになるのか」という環境差を整理しておきましょう。ここを理解しておくと、今後あらゆるデプロイエラーを自力で即座に解決できるようになります。
ローカルPC環境とCloudflareビルドサーバーの4つの決定的な違い
Cloudflare Pagesは、GitHubへのプッシュを検知すると、毎回まっさらな「Ubuntu(Linux)ベースの仮想コンテナ」を立ち上げ、そこにGitHubのコードだけをクローンしてゼロからビルドを実行します。
| 環境要素 | ローカル環境(Mac / Windows) | Cloudflare Pages(ビルド環境) | 引き起こされる典型エラー |
|---|---|---|---|
| Node.jsバージョン | 自分がインストールした最新版(v20 / v22等) | ビルドシステムのデフォルト値(古い場合あり) | SyntaxError / Unsupported engine |
環境変数(.env) |
プロジェクト直下の .env ファイルを自動参照 |
.gitignore により .env は存在しない |
APIキーが undefined になりデータ取得失敗 |
| OSのファイルシステム | 大文字・小文字を区別しない(Case-Insensitive) | Linuxのため大文字・小文字を厳密に区別 | Could not resolve "../components/..." |
| パッケージ導入状態 | 過去の node_modules キャッシュが残存 |
ロックファイルに基づき毎回クリーン導入 | npm ERR! code EUSAGE / ERESOLVE |
【10秒で特定】ビルドログの「どこ」を見れば原因がわかるのか?
Cloudflare Pagesの「Deployments(デプロイ)」画面で失敗したジョブを開き、「Build log(ビルドログ)」を確認するときは、一番下の行(Failed: build command exited with code: 1)から10〜20行だけ上へ遡った箇所を見てください。そこに必ず以下のいずれかのキーワードが記録されています。
| ビルドログに出ているエラー文言 | 該当する原因と対策セクション |
|---|---|
Node.js version v16.x / v18.x is not supported または SyntaxError: Unexpected token |
➔ 【原因1】Node.jsのバージョン不一致 |
serviceDomain is required / apiKey is required / GET ... 401 Unauthorized |
➔ 【原因2】microCMS等の環境変数の未登録 |
RollupError: Could not resolve "..." from "src/pages/..." |
➔ 【原因3】ファイル名の大文字・小文字の不一致 |
npm ERR! cipm can only install packages with an existing package-lock.json / ERESOLVE |
➔ 【原因4】ロックファイルと依存関係の不整合 |
Error: Output directory "dist" not found / Adapter is required |
➔ 【原因5】ビルド出力先・SSRアダプターの設定ミス |
💡 Astro × microCMS × Cloudflare Pagesの初期構築・自動デプロイの全体像はこちら:
・【実録】Astro × microCMS × Cloudflare Pagesで爆速メディアを立ち上げる!初期構築からトラブルシューティング、自動化まで完全解説
・GitHub × Cloudflare Pagesで実現する「完全無料・自動デプロイ環境」の作り方
【原因1】Node.jsのバージョン不一致(最も多い初期エラー)
Astro v4およびv5系は、動作要件として新しいNode.js(v18.17.1 以上、推奨は v20 LTS または v22 LTS)を要求します。
しかし、Cloudflare Pagesのプロジェクト設定やBuild Systemの世代(v1 / v2)によっては、古いNode.jsバージョンでビルドが走ってしまい、以下のようなエラーで即死するケースが頻発します。
14:02:11.450 Node.js v18.16.0 is not supported by Astro!
14:02:11.451 Please upgrade Node.js to a supported version: ">=18.17.1 <19.0.0 || >=20.3.0"
14:02:11.512 Failed: build command exited with code: 1
解決手順A:Cloudflareダッシュボードの環境変数に「NODE_VERSION」を設定する
最も手軽な解決策は、Cloudflare Pagesの管理画面から使用するNode.jsのバージョンを明示的に指定することです。
- Cloudflareダッシュボードを開き、左メニューの「Workers & Pages」から対象のAstroプロジェクトを選択します。
- 画面上部の「Settings(設定)」タブ ➔ 左メニューの「Environment variables(環境変数)」(または「Variables and Secrets」)を開きます。
- 「Production(本番環境)」と「Preview(プレビュー環境)」の両方に、以下の変数を追加して保存します。
- Variable name(変数名):
NODE_VERSION - Value(値):
20(またはローカルで動作確認している20.18.0や22などのバージョン番号)
- Variable name(変数名):
- 設定画面内の「Build system version(ビルドシステムバージョン)」が古い(Version 1)になっている場合は、最新の「Version 2」へ切り替えておきます。
解決手順B(推奨):プロジェクト直下に「.nvmrc」または「.node-version」を配置する
管理画面での設定に加えて、プロジェクトのルートディレクトリ(package.json と同じ階層)に .nvmrc という名前のファイルを作成し、Gitへコミットしておく方法が実務では最も確実です。Cloudflare Pagesはこのファイルを自動的に読み取ってNode.jsのバージョンを切り替えてくれます。
# プロジェクト直下に .nvmrc ファイルを作成し、1行だけ記述する
20.18.0
あわせて package.json にも engines フィールドを追記しておくと、ローカル環境とクラウド環境のバージョン基準を完全に統一できます。
{
"name": "my-astro-site",
"type": "module",
"version": "1.0.0",
"engines": {
"node": ">=20.3.0"
},
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview"
}
}
【原因2】microCMS等の環境変数(.env)がCloudflare側に登録されていない
Node.jsのバージョンを合わせたのに、今度はビルドの途中(generating static routes の段階)で以下のようなエラーが出て落ちる場合、原因は100%「環境変数(APIキーやサービスドメイン)の未登録」です。
generating static routes
▶ src/pages/index.astro
error serviceDomain is required
File:
/opt/buildhome/repo/node_modules/microcms-js-sdk/dist/cjs/microcms-js-sdk.js:1:1240
...
Failed: build command exited with code: 1
あるいは、SDKを使わずに fetch() で直接叩いている場合は TypeError: fetch failed や 401 Unauthorized、404 Not Found が表示されます。
なぜローカルの「.env」がCloudflareに反映されないのか?
ローカル開発時に作成した .env ファイル(MICROCMS_SERVICE_DOMAIN や MICROCMS_API_KEY を記述したファイル)は、セキュリティ上の理由から .gitignore によってGitHubへのアップロード対象から除外されています。
つまり、GitHubにもCloudflare Pagesのサーバー上にも .env ファイルは存在しないため、コード内の import.meta.env.MICROCMS_API_KEY が空っぽ(undefined)になってビルドがクラッシュしているのです。
⚠️ 絶対にやってはいけないNG対処法:
「.envがGitHubに上がっていないなら、.gitignoreから.envを消してGitHubへプッシュすれば動くのでは?」と考えるのは非常に危険です。リポジトリからAPIキーが流出し、不正アクセスやデータ改ざんの被害に遭うため、.envファイル自体は絶対にGitHubへプッシュしないでください。
解決手順:Cloudflare Pagesの「Environment variables」にAPIキーを暗号化登録する
- 手元のVS Code等で
.envファイルを開き、設定している変数名と値を確認します。 - Cloudflareダッシュボードの 「Settings」➔「Environment variables(または Variables and Secrets)」 を開きます。
- 「Add variable(変数を追加)」をクリックし、ローカルの
.envと1文字も違わない正確な変数名で以下のように登録します。- 変数1:
MICROCMS_SERVICE_DOMAIN/ 値: あなたのサービスID(例:core-media-lab※.microcms.ioは含めない) - 変数2:
MICROCMS_API_KEY/ 値: microCMSのシークレットAPIキー(※種類を「Encrypt / Secret(暗号化)」に切り替えて保存すると画面上から伏せ字になり安全です)
- 変数1:
- 重要ポイント: 必ず「Production(本番)」だけでなく、「Preview(プレビュー環境)」側にも同じ変数を設定してください(プルリクエストやブランチプッシュ時のビルドで落ちるのを防ぐためです)。
- 保存後、「Deployments」タブに戻り、失敗したビルドの右端にある「Retry deployment(再デプロイ)」を実行します。
【再発防止】どの環境変数が足りないかを一瞬で表示するガードコード
今後新しい環境変数を追加した際に「何の変数をCloudflareへ登録し忘れたのか」がビルドログ上で一目で分かるよう、src/lib/microcms.ts(クライアント初期化ファイル)の先頭に以下のようなチェック処理を入れておくのがおすすめです。
// src/lib/microcms.ts
import { createClient } from 'microcms-js-sdk';
const serviceDomain = import.meta.env.MICROCMS_SERVICE_DOMAIN;
const apiKey = import.meta.env.MICROCMS_API_KEY;
// ビルド時に環境変数が未設定なら、原因を日本語で明確に出力して停止する
if (!serviceDomain) {
throw new Error('【環境変数エラー】MICROCMS_SERVICE_DOMAIN が設定されていません。Cloudflare PagesのEnvironment variablesを確認してください。');
}
if (!apiKey) {
throw new Error('【環境変数エラー】MICROCMS_API_KEY が設定されていません。Cloudflare PagesのEnvironment variablesを確認してください。');
}
export const client = createClient({
serviceDomain,
apiKey,
});
この6行を入れておくだけで、万が一設定漏れがあっても、ビルドログに日本語で 【環境変数エラー】MICROCMS_API_KEY が設定されていません とくっきり表示されるため、原因調査に時間を奪われることがなくなります。
【原因3】ファイル名・インポートパスの「大文字・小文字」不一致(Windows・MacとLinuxの罠)
Node.jsのバージョンも環境変数も完璧に設定したのに、ビルドログに以下のような Could not resolve(または Module not found) というエラーが出て落ちる場合、原因のほとんどは「ファイル名の大文字・小文字のズレ」です。
error during build:
RollupError: Could not resolve "../components/Header.astro" from "src/layouts/Layout.astro"
at error (file:///opt/buildhome/repo/node_modules/rollup/dist/es/shared/parseAst.js:337:30)
...
Failed: build command exited with code: 1
なぜ自分のパソコンではエラーにならずに動くのか?
普段私たちが使っているWindowsやMac(標準のファイルシステム)は、ファイル名の大文字と小文字を区別しない(Case-Insensitive)仕様になっています。そのため、実際のファイル名が小文字の header.astro であっても、コード内で import Header from '../components/Header.astro' と大文字で書いてしまえば、ローカル環境では何事もなく動いてしまいます。
しかし、Cloudflare Pagesのビルドサーバーが動いているLinux(Ubuntu)環境は、大文字と小文字を完全に別ファイルとして厳密に区別(Case-Sensitive)します。さらに厄介なことに、Gitはデフォルト設定だと「ファイル名の大文字・小文字だけの変更(例:header.astro ➔ Header.astro へのリネーム)」を差分として検知してくれないため、手元でファイル名を直したつもりでもGitHub上では古い小文字のまま残ってしまうという罠があります。
解決手順:git mv コマンドでGit上のファイル名を確実に修正する
VS Codeのエクスプローラー上で単にファイル名を書き換えるのではなく、ターミナルで以下のGitコマンドを実行して「大文字・小文字の区別」をGitに強制認識させます。
# 1. Gitが大文字・小文字の違いを検知するように設定を変更
git config core.ignorecase false
# 2. git mv コマンドで明示的にリネーム(一度別名を経由すると100%確実に反映されます)
git mv src/components/header.astro src/components/ temp_header.astro
git mv src/components/temp_header.astro src/components/Header.astro
# 3. 変更をコミットしてGitHubへプッシュ
git add .
git commit -m "fix: コンポーネントファイル名の大文字小文字を修正"
git push
これでGitHub上のファイル名と import 文のパスが一字一句完全に一致し、Cloudflare PagesのLinux環境でも正常にモジュールが読み込まれるようになります。
💡 VS CodeとGitの基本コマンド・デプロイ手順のおさらいはこちら:
・サーバー代0円で爆速運用!VS Codeの3コマンドで実現するAstro × Cloudflare Pages自動デプロイ術
【原因4】package-lock.jsonの競合・依存関係エラー(npm ci の失敗対策)
Astro本体のビルドが始まる前の段階(Installing project dependencies のフェーズ)で以下のようなエラーが出て止まる場合は、package.json と package-lock.json の整合性が崩れているか、パッケージ間のピア依存関係(Peer Dependencies)が競合しています。
Installing project dependencies: npm clean-install --progress=false
npm error code EUSAGE
npm error `npm ci` can only install packages when your package.json and package-lock.json are in sync.
npm error Missing: @astrojs/[email protected] from lock file
...
Error: Exit with error code: 1
なぜCloudflare Pagesでは「npm install」ではなく「npm clean-install(npm ci)」が走るのか?
Cloudflare Pagesはビルドの再現性を担保するため、リポジトリ内に package-lock.json が存在すると、通常の npm install ではなく厳格な npm clean-install(npm ci) を自動実行します。このコマンドは「package.json と package-lock.json の中身が1ミリでも食い違っていると即座にエラーで停止する」という仕様を持っています。
解決手順:ローカルで node_modules とロックファイルを再生成してプッシュする
手元のPCでパッケージの追加や削除を繰り返した際にロックファイルがズレてしまった場合は、以下の手順でクリーンに作り直してから再プッシュすれば一発で解決します。
# 1. ローカルの node_modules と package-lock.json を一度削除する
rm -rf node_modules package-lock.json
# 2. キャッシュをクリアして最新状態で再インストール(新しい package-lock.json を生成)
npm install
# 3. 念のためローカルで本番ビルドが通るか確認
npm run build
# 4. 新しい package-lock.json をGitHubへプッシュ
git add package.json package-lock.json
git commit -m "fix: package-lock.jsonの依存関係を再生成"
git push
※もしReact系やTailwind関連のライブラリを導入していて npm error code ERESOLVE unable to resolve dependency tree が出る場合は、プロジェクト直下に .npmrc ファイルを作成し、以下の1行を記述してプッシュすることで回避できます。
legacy-peer-deps=true
【原因5】ビルド出力ディレクトリ(dist)やCloudflare SSRアダプターの設定ミス
ビルドコマンド自体は最後まで走って Complete! と出ているのに、最後の最後で Error: Output directory "dist" not found が出たり、デプロイ後の画面を開くと500エラーになる場合は、Cloudflare Pages側のビルド設定またはAstroのアダプター構成にズレがあります。
チェックポイント1:Cloudflare Pagesの「Build output directory」を確認する
Cloudflareダッシュボードの 「Settings」➔「Build & deployments(ビルドとデプロイ)」 を開き、設定値が以下の通りになっているか確認してください。
| 設定項目 | 正しい設定値(Astro標準) | よくある間違い |
|---|---|---|
| Framework preset | Astro |
None や Next.js になっている |
| Build command | npm run build(または astro build) |
npm run dev になっている |
| Build output directory | dist |
build や public になっている |
チェックポイント2:SSR(output: 'server' / 'hybrid')利用時の注意点
astro.config.mjs でSSR(サーバーサイドレンダリング)を有効にして @astrojs/cloudflare アダプターを使用している場合、Cloudflareのランタイム(Workerd)はNode.js標準モジュール(fs、path、crypto 等)の一部をそのままでは実行できないという制約があります。
- 個人ブログやメディア運営であれば、原則として
astro.config.mjsでoutput: 'static'(デフォルトの完全静的生成:SSG)にしておくのが最もエラーが少なく、表示速度も最速になります。 - どうしてもSSR機能(APIエンドポイント等)が必要な場合は、
astro.config.mjsのアダプター設定に互換フラグを設定するか、重いバックエンド処理は無理にCloudflare Workers上で動かさず、専用のVPS環境(Docker上のn8nやDify、Python APIサーバー等)へ切り出してWebhookやAPIで疎結合に連携する構成が圧倒的に安定します。
💡 あわせて読みたい(AstroのSEO・画像最適化トラブル解決ガイド):
・【Astro】Search Consoleで「サイトマップが取得できませんでした」となる原因と解決手順
・microCMSの画像最適化(imgix)とAstroを組み合わせてPageSpeed Insights 100点を目指す高速化ガイド
【予防策】GitHubへプッシュする前にローカルで100%エラーを検知する習慣
普段の執筆やデザイン修正では npm run dev(開発サーバー)だけを使って確認しがちですが、astro dev はページを開いたときに遅延評価されるため、別ページの型エラーやインポートミスを見逃したままGitHubへプッシュしてしまいがちです。
機能追加やコンポーネントの修正を行った際は、GitHubへプッシュする前に必ず手元のターミナルで以下のワンライナーを実行する癖をつけましょう。
# 型チェックと本番ビルドが最後まで通るかをローカルで事前検証する
npx astro check && npm run build
このコマンドがローカルでエラーなく完走し、かつ .nvmrc と環境変数がCloudflare側に揃っていれば、Cloudflare Pagesでのビルド失敗はほぼゼロに抑え込むことができます。
まとめ:Cloudflare Pagesのビルドエラーは「環境差」を揃えれば100%防げる
本記事では、Cloudflare PagesでAstroサイトのビルドが失敗する5大原因と、それぞれの具体的な解決手順を解説しました。
- 【原因1】Nodeバージョン不一致: Cloudflareの環境変数
NODE_VERSIONに20(または22)を設定し、リポジトリ直下に.nvmrcを配置する。 - 【原因2】環境変数の未登録:
.envはGitHubに上がらないため、MICROCMS_API_KEY等をCloudflareの「Production」と「Preview」の両方に暗号化登録する。 - 【原因3】大文字・小文字のパス不一致: Linux環境は厳密に区別するため、
git config core.ignorecase falseとgit mvでファイル名を正確に揃える。 - 【原因4】ロックファイルの不整合:
node_modulesとpackage-lock.jsonを再生成してコミットし、npm ciエラーを解消する。 - 【原因5】出力先と役割分担: 出力ディレクトリが
distになっているか確認し、フロントエンド(Astro SSG)と重いバックエンド自動化処理(VPS環境)を綺麗に分離する。
一度この初期設定と環境統一を済ませてしまえば、以降は記事を入稿するだけで数分で世界最速クラスのWebサイトが自動更新され続けます。もしCloudflareの制限を受けないバックエンド自動化(Difyやn8n、Pythonバッチ処理など)も組み合わせてメディア運営をさらに加速させたい方は、以下のVPS比較ガイドもあわせてチェックしてみてください!