サイトを作ったあと、FTPでファイルを上げていませんか。ローカルで直して、FTPクライアントを開いて、変更したファイルを探して、アップロード。上げ忘れが起きるし、どれが最新か分からなくなる。
GitHubとCloudflareをつないでおくと、この作業がまるごと消えます。コードをpushしたら勝手にビルドされて、数十秒後には公開サイトが新しくなっている。FTPクライアントを開くことは二度とありません。
このサイト(morino-web.com)も同じ構成で動いています。記事を書いてコミットしてpushすれば公開される。この記事では、その環境をゼロから作る手順と、実際に運用してみて決めた設定を書いていきます。
- GitHubにpushするだけでサイトが更新される仕組みの作り方
- Cloudflare側で設定する項目と、それぞれ何を書くのか
- 本番用ブランチとプレビュー用ブランチの使い分け
- 独自ドメインをつなぐ手順
- PagesとWorkersの違いと、いまPagesが「legacy」扱いになっていること
何ができるようになるのか
やることは単純で、GitHubのリポジトリとCloudflareのプロジェクトを1回つなぐだけです。あとは自動で回ります。
つないだあとの流れはこうです。ローカルで編集してcommitしてpush。Cloudflare側がそれを検知して、指定したビルドコマンドを走らせて、出来上がったファイルを世界中のサーバーに配る。ここまで全部自動です。
嬉しいのは本番だけじゃないところで、mainブランチ以外にpushすると「プレビューデプロイ」という別URLが自動で作られます。公開サイトには影響しないまま、本番と同じ環境で見られる。デザイン変更を人に見せて確認をもらう、みたいなときに便利です。
プルリクエストを出すと、そのPRにビルド結果のコメントが自動で付きます。過去のビルドが履歴として残るので、どの変更でどうなったか追えるようになっています。
なぜCloudflareなのか
無料でサイトを公開できるサービスは他にもあります。ここは正直に、このサイトで選んだときの判断を書きます。
いちばん大きかったのがライセンスの条件です。Vercelの無料プラン(Hobby)は商用利用ができません。このサイトはコーポレートサイトを含むので、その時点で選択肢から外れました。仕事のサイトを載せるつもりなら、ここは最初に確認しておいたほうがいい項目です。
もうひとつが料金の形。Cloudflareは転送量(帯域)による課金がありません。記事が急に読まれても請求が跳ねない。ビルド回数の無料枠も広めなので、記事を書くたびにビルドが走る運用と相性が良かった。
あとはDNSとSSLとCDNを1か所で管理できること。ドメインの設定もSSL証明書も同じ画面で完結するので、「証明書の更新を忘れて切れる」みたいな事故が起きません。
このサイトはもともとWordPressでした。移行の直接のきっかけは脆弱性で、PHPもデータベースも管理画面も持たない構成にすれば、攻撃される面そのものが無くなる、という判断です。静的サイトへの移行を考えているなら、この「守るものが減る」という利点は料金以上に効きます。
公開までの手順
ここからが本題です。GitHubにリポジトリがある状態から始めます。まだGitを触ったことがなければ、先にGit入門を読んでからのほうがスムーズです。
-
「Workers & Pages」を開く
Cloudflareにログインして、左メニューの Build > Compute にある「Workers & Pages」を選びます。アカウントが無ければ先に作ってください。無料です。
-
「Create application」を押す
プロジェクト一覧の右上にあります。まだ何も作っていなければ一覧は空のままで問題ありません。
-
Pagesの入口へ進む
「Make something new」という画面になります。ここで注意したいのが、Pagesへのリンクが下のほうに小さく置かれていること。「Need to use the legacy Pages workflow?」に続く「Continue to Pages」を押します。
-
Gitから取り込む
「Import an existing Git repository」の「Get started」を選びます。下の「Drag and drop your files」はファイルを直接アップロードする方式で、今回は使いません。
-
GitHubを認証する
GitHubのサインイン画面が出ます。「Cloudflare Workers and Pages」というGitHub Appがインストールされ、アクセスを許可するリポジトリを聞かれます。
-
リポジトリを選ぶ
Cloudflareの画面に戻ると、許可したリポジトリが並びます。公開したいものを選んで「Begin setup」。
-
ビルド設定を書いてデプロイ
「Set up builds and deployments」でビルドの内容を指定し、「Save and Deploy」。初回のビルドが終わると
プロジェクト名.pages.devのURLで公開されています。
以降はpushするだけです。この画面に戻ってくる必要はありません。
順番に画面を見ていきます。まずは入口。

左メニューの Build > Compute の中にあります

プロジェクトがまだ無ければ一覧は空のままで大丈夫です
次の画面が、いま一番わかりにくいところです。

Pagesへの導線は下部のリンクに移動しています
上に並んでいる「Continue with GitHub」はWorkersの経路です。Pagesを使うなら下のリンクから入ります。この違いについては記事の後半で改めて触れます。

下の「Drag and drop your files」はファイルを直接上げる方式です
ここでGitHub側に飛ばされます。

要求される権限もこの画面で確認できます
全リポジトリを許可するか、選んだものだけにするかを聞かれます。Cloudflare公式も「Only select repositories」を推奨しています。権限を見ると、コードやデプロイに対する書き込みまで含まれています。公開するリポジトリだけを選んでおけば、関係ないプロジェクトにその権限を渡さずに済みます。
許可が済むとCloudflareの画面に戻ります。

一覧に出てこないときは、GitHub App の許可範囲に入っていません
なお、個人アカウントではなく組織(Organization)のリポジトリをつなぐ場合は、組織のオーナー権限か「GitHub Apps Manager」ロールが必要です。権限が無いと連携の途中で止まるので、先に確認しておくと詰まりません。
ビルド設定で書くこと
最後の画面です。ここを間違えると真っ白なページが公開されるので、意味を押さえておくと安心です。

①を選べば②③は自動で埋まります
| 項目 | 何を書くか |
|---|---|
| Project name | プロジェクト名。そのまま 〇〇.pages.dev のURLになります |
| Production branch | 本番として公開するブランチ。通常は main |
| ① Framework preset | 使っているフレームワークを選ぶと、②③が自動で入ります |
| ② Build command | ビルドを実行するコマンド。例:npm run build |
| ③ Build output directory | 完成したファイルが出るフォルダ。例:dist |
| Root directory (advanced) | リポジトリ内のどこを起点にするか。モノレポで使います |
| Environment variables (advanced) | APIキーなど、ビルド時に必要な環境変数 |
いちばん効くのが Framework preset です。Astro や Next.js を選べばビルドコマンドと出力先が自動で入るので、下の2つを自分で考える必要がなくなります。素のHTMLサイトなら None のままでかまいません。
自分で書く場合につまずきやすいのが、その下の2つです。
Build output directory は、フレームワークによって名前が違います。Astroなら dist、Next.jsの静的出力なら out、Viteなら dist。手元で一度ビルドしてみて、実際にどのフォルダにHTMLが出るか確認するのが確実です。HTMLファイルが直接入っているフォルダを指定します。入力欄の左に / が固定で表示されているので、ここに書くのはそこから先のパスだけです。
Root directoryを使うのは、リポジトリのルートに package.json が無いときです。たとえば apps/site/ の中にサイトが入っているなら、ここに apps/site と書く。ルート直下にサイトがあるなら触らなくて大丈夫です。この項目と Environment variables は「(advanced)」の折りたたみに入っているので、必要なときだけ開きます。
ビルドコマンドを持たない素のHTMLサイトなら、Build commandは空でかまいません。Build output directoryにHTMLがあるフォルダを指定するだけで公開できます。
モノレポで複数サイトを配信する場合
このサイトはコーポレート・ポートフォリオ・ブログの3つを1つのドメインの下に置いています。同じことをやろうとするとひとつ壁があって、Cloudflare Pagesは1プロジェクト=1ドメインが基本です。3つのプロジェクトを作ると、ドメインも3つに分かれてしまう。
なので、3つを個別にビルドしてから1つの output/ フォルダに結合し、それをまとめてデプロイする方式にしています。Cloudflareから見れば普通の1プロジェクトで、中身が3サイトぶんある、という形。
この構成で注意が必要なのがリダイレクトの設定ファイルです。Cloudflare Pagesは _redirects というファイルでリダイレクトを設定できるのですが、これは最終的な出力のルートに無いと読まれません。結合方式だと、ルートに展開されるのはコーポレートサイトなので、apps/corporate/public/_redirects に置く必要がある。ブログ側に置いても効きません。
サブディレクトリ構成にするなら、フレームワーク側の設定も要ります。Astroの場合は base: '/info' のように配信パスを指定して、テンプレート内のリンクは import.meta.env.BASE_URL を経由させる。/posts/xxx のようにハードコードすると404になります。
独自ドメインをつなぐ
.pages.dev のままでも公開はできますが、自分のドメインを当てるのは数分で終わります。
プロジェクトの「Custom domains」からドメインを追加して、あとはDNSの設定です。ドメイン自体をCloudflareで管理しているなら、レコードは自動で追加されるのでほぼクリックだけ。他社でドメインを取っている場合は、指示されたCNAMEレコードを登録します。
SSL証明書は自動で発行されて自動で更新されます。証明書の期限を気にする必要はありません。ここが冒頭に書いた「DNSとSSLを1か所で管理できる」利点で、ドメインもCloudflareに移しておくと、この作業がほぼ消えます。
PagesとWorkers、どちらを使うか
Cloudflareには静的サイトを配信する経路が2つあります。ここまで説明してきたPagesと、Workersに静的ファイルを載せる方法です。どちらもGitHub連携ができて、pushで自動デプロイされる点は同じ。
ただ、扱いには差が出はじめています。手順3で見た画面を思い出してください。Pagesへのリンクにはこう書かれていました。
Need to use the legacy Pages workflow? Continue to Pages
Cloudflare自身がPagesを「legacy」と呼んでいます。上に大きく並んでいた「Continue with GitHub」がWorkersの経路で、そちらが既定の入口になっている。今すぐ使えなくなる話ではありませんが、力が入っている方向は画面を見れば分かります。
そのうえで、公式ドキュメントに載っている機能の差分を並べます。
| Pages | Workers | |
|---|---|---|
| 静的アセットのリクエスト課金 | ― | 無料 |
| Cron Triggers / Durable Objects | 使えない | 使える |
| Early Hints | 対応 | 条件付き |
| Cloudflare外のドメイン | 対応 | 非対応 |
Workersのほうが機能は広いです。定期実行や状態を持つ処理まで同じ仕組みに載せられるので、後からサイトに動的な機能を足したくなったときに強い。
一方でPagesにしかできないこともあって、Cloudflareで管理していない外部ドメインを当てられるのは今のところPagesだけです。ドメインを他社に置いたまま運用したいなら、ここは判断の分かれ目になります。
Workersを使う場合、GitHub連携の入口が違って、プロジェクトの「Settings」→「Builds」→ Git Repositoryの「Manage」→「+ Add account」から進みます。インストールするGitHub Appは同じ「Cloudflare Workers and Pages」です。
このサイトは、設計した時点でPagesを選んでそのまま運用しています。静的なページを配るだけなら足りていて、乗り換える差し迫った理由は今のところありません。
とはいえ、これから新しく作るならWorkersから入るほうが自然だと思います。画面の作りがそうなっていますし、機能も広い。この記事でPagesの手順を書いたのは、既存のプロジェクトがPagesで動いている人が多いからで、ゼロから始めるなら上の「Continue with GitHub」を押すところから試してみてください。ビルド設定で書く内容は、どちらの経路でもほとんど変わりません。
まとめ
| やること | 内容 |
|---|---|
| 連携 | 「Workers & Pages」→「Create application」→ 下部の「Continue to Pages」→「Import an existing Git repository」 |
| 設定 | Framework presetを選べばビルドコマンドと出力フォルダは自動。モノレポならRoot directoryも |
| 公開 | 「Save and Deploy」で 〇〇.pages.dev が発行される |
| 以降 | mainにpushで本番更新、他ブランチはプレビューURLが自動生成 |
| ドメイン | 「Custom domains」から追加。SSLは自動発行・自動更新 |
一度つないでしまえば、あとは普段のGitの操作がそのまま公開作業になります。「公開する」という独立した作業が無くなるのが、この構成のいちばん大きな変化だと思っています。
ひとつ引っかかる点を挙げるなら、ビルドがCloudflare側で走るので、手元では通ったのにデプロイで落ちることがあります。Node.jsのバージョン違いが原因のことが多い。環境変数で NODE_VERSION を指定しておくと揃えられるので、ビルドログを見て落ちていたらまずそこを疑ってください。
あわせて読みたい
参考
- Git integration - Cloudflare Pages(Cloudflare公式ドキュメント) — Pagesの連携手順とビルド設定項目を参照
- GitHub integration - Cloudflare Workers(Cloudflare公式ドキュメント) — GitHub Appの名称、必要な権限、Workers側の連携手順を参照
- Migrate from Pages to Workers(Cloudflare公式ドキュメント) — PagesとWorkersの機能差分を参照
