TOP ──BLOG ──Web

CloudflareとGitHubでサイトを公開する方法|pushだけで反映される仕組み作り

サイトを作ったあと、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から移行するなら

このサイトはもともとWordPressでした。移行の直接のきっかけは脆弱性で、PHPもデータベースも管理画面も持たない構成にすれば、攻撃される面そのものが無くなる、という判断です。静的サイトへの移行を考えているなら、この「守るものが減る」という利点は料金以上に効きます。

公開までの手順

ここからが本題です。GitHubにリポジトリがある状態から始めます。まだGitを触ったことがなければ、先にGit入門を読んでからのほうがスムーズです。

  1. 「Workers & Pages」を開く

    Cloudflareにログインして、左メニューの Build > Compute にある「Workers & Pages」を選びます。アカウントが無ければ先に作ってください。無料です。

  2. 「Create application」を押す

    プロジェクト一覧の右上にあります。まだ何も作っていなければ一覧は空のままで問題ありません。

  3. Pagesの入口へ進む

    「Make something new」という画面になります。ここで注意したいのが、Pagesへのリンクが下のほうに小さく置かれていること。「Need to use the legacy Pages workflow?」に続く「Continue to Pages」を押します。

  4. Gitから取り込む

    「Import an existing Git repository」の「Get started」を選びます。下の「Drag and drop your files」はファイルを直接アップロードする方式で、今回は使いません。

  5. GitHubを認証する

    GitHubのサインイン画面が出ます。「Cloudflare Workers and Pages」というGitHub Appがインストールされ、アクセスを許可するリポジトリを聞かれます。

  6. リポジトリを選ぶ

    Cloudflareの画面に戻ると、許可したリポジトリが並びます。公開したいものを選んで「Begin setup」。

  7. ビルド設定を書いてデプロイ

    「Set up builds and deployments」でビルドの内容を指定し、「Save and Deploy」。初回のビルドが終わると プロジェクト名.pages.dev のURLで公開されています。

以降はpushするだけです。この画面に戻ってくる必要はありません。

順番に画面を見ていきます。まずは入口。

Cloudflareダッシュボードの左サイドバー。Build配下のCompute内にある「Workers & Pages」を赤枠で囲み、「最初にここを開く」と注記している

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

Workers & Pagesのプロジェクト一覧画面。右上の青い「Create application」ボタンを赤枠で囲み、「ここから作成」と注記している

プロジェクトがまだ無ければ一覧は空のままで大丈夫です

次の画面が、いま一番わかりにくいところです。

Cloudflareの「Make something new」画面。Continue with GitHubなど5つの選択肢が並び、その下の「Need to use the legacy Pages workflow? Continue to Pages」を赤枠で囲んで「Pages を使うならこのリンク」と注記している

Pagesへの導線は下部のリンクに移動しています

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

Cloudflare Pagesの「Get started」画面。「Import an existing Git repository」の「Get started」ボタンを赤枠で囲み、「Git から取り込む」と注記している

下の「Drag and drop your files」はファイルを直接上げる方式です

ここでGitHub側に飛ばされます。

GitHubの設定画面に表示されたCloudflare Workers and PagesのGitHub App。Repository accessの「Only select repositories」を赤枠で囲み、「公開するものだけ選ぶ」と注記している。Permissions欄にはRead access to metadata、administrationやcode、deploymentsなどへのRead and writeが並んでいる

要求される権限もこの画面で確認できます

アクセス範囲は絞る

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

許可が済むとCloudflareの画面に戻ります。

Cloudflare Pagesのリポジトリ選択画面。「Select a repository」の下に並ぶリポジトリ一覧を赤枠で囲んで丸数字の1、右下の「Begin setup」ボタンを赤枠で囲んで丸数字の2を付けている

一覧に出てこないときは、GitHub App の許可範囲に入っていません

なお、個人アカウントではなく組織(Organization)のリポジトリをつなぐ場合は、組織のオーナー権限か「GitHub Apps Manager」ロールが必要です。権限が無いと連携の途中で止まるので、先に確認しておくと詰まりません。

ビルド設定で書くこと

最後の画面です。ここを間違えると真っ白なページが公開されるので、意味を押さえておくと安心です。

Cloudflare Pagesの「Set up builds and deployments」画面。Framework presetに丸数字の1、Build commandに丸数字の2、Build output directoryに丸数字の3を付けて赤枠で囲んでいる。Production branchはmain、下部にRoot directory (advanced)とEnvironment variables (advanced)の折りたたみ、右下にSave and Deployボタンがある

①を選べば②③は自動で埋まります

項目 何を書くか
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 を指定しておくと揃えられるので、ビルドログを見て落ちていたらまずそこを疑ってください。

あわせて読みたい

参考

代表 morino のポートレート

この記事を書いた人

morino

Webサイト・ECサイト制作、SNS運用、体験型ゲーム制作をひとりで手がけています。