コードを push する。
数十秒後、世界に出る。
GitHub と Cloudflare Workers をつなぐ初期設定ガイド。一度組めば、あとは git push するだけで、自動ビルド・デプロイが走り、独自ドメインには常に最新版が映ります。
What you get
この構成でできること
接続方式は2通りありますが、設定が最も簡単な Workers Builds(Cloudflare 純正の Git 連携) を推奨構成として解説します。API トークンの管理が不要で、ダッシュボード操作だけで完結します。
push が唯一のトリガー
本番ブランチへの push を検知して自動でビルド・デプロイ。手動のデプロイ作業がなくなります。
独自ドメインに自動反映
ドメインは常に最新の本番デプロイを指すため、ビルド完了後そのまま反映されます。
GitHub で状態確認
デプロイの成否はコミット横のチェックに表示。画面を離れずに監視できます。
Architecture
構成図
開発から公開、そしてユーザーのリクエスト処理までの全体像です。更新は上から下へ(push → 自動ビルド → Worker → 公開)流れ、ユーザーのアクセスは独自ドメイン経由で Worker が処理し、D1 を読み書きします。
Prerequisites
前提条件
| 項目 | 内容 |
|---|---|
| GitHub アカウント | リポジトリを作成できること |
| Cloudflare アカウント | 無料プランで可 |
| 独自ドメイン | Cloudflare の DNS(ゾーン)配下にあること。 ネームサーバーを Cloudflare に向けて移管済みである必要があります |
| Node.js | LTS 版を推奨。node -v で確認 |
| Git | git --version で確認 |
*.workers.dev のサブドメインだけで試す場合、独自ドメインの前提は不要です。Language & Runtime
開発言語・ランタイム
Worker は Node.js サーバーではなく、Cloudflare 独自の V8 ベースのエッジランタイム(workerd) 上で動きます。書く言語は JavaScript / TypeScript が標準で、C3 の雛形も既定で TypeScript を選べます。前提条件の Node.js は、ローカルでのビルドやツール(npm・wrangler)実行のためのものであって、本番でコードを動かす実行環境ではありません。
JavaScript / TypeScript
最も情報が多く、まず選ぶ言語。src/index.ts にリクエストハンドラを書く。型の付く TypeScript を推奨。
Python
Workers の Python 対応。src/entry.py を起点に、Python で Worker を記述できる(機能は発展途上)。
Rust / WebAssembly
workers-rs 経由の Rust など、WebAssembly にコンパイルできる言語も動かせる。
wrangler.jsonc の compatibility_flags に nodejs_compat を加えると利用できます。ただし Node.js の全 API が使えるわけではない点に注意してください。Setup · 6 steps
構築手順
上から順に進めれば、push するだけで本番反映される状態が完成します。
ローカルがある場合:下の手順01から C3 で雛形を作るのが最短です。
ローカルが無い場合:手順01〜02を飛ばし、GitHub の Web UI でリポジトリとファイルを作成→ 手順03でダッシュボード接続、という流れでブラウザだけで完結できます。ただし静的サイトと Worker で
wrangler.jsonc が少し違い、ここを外すとデプロイが失敗します——すぐ下の「ローカル無しの2つの型」を必ず確認してください。✘ [ERROR] The entry-point file at "src/index.ts" was not found.原因:
wrangler.jsonc に "main": "src/index.ts" があるのに、その src/index.ts が存在しないため。C3(手順01)ならこのファイルは自動生成されますが、GitHub の Web UI で手動作成した場合は、自分で用意しない限り存在しません。npx wrangler deploy は「入口(エントリーポイント)」を探して失敗します。用途に応じて次の A / B のどちらかで解決します。wrangler.jsonc から main の行を削除し、assets だけにします。エントリーポイントが要求されず、静的アセット配信としてそのままデプロイできます。HTML/CSS/JS を置くだけのサイト(当ドキュメントライブラリなど)はこれで十分。{
"name": "your-app",
"compatibility_date": "YYYY-MM-DD",
"assets": { "directory": "./public" } // 静的ファイルの置き場所(ビルドで生成するなら dist 等)
}npx wrangler deploy のままでOK(main が無いのでアセットのみ配信)。Build command は、ビルドで静的ファイルを生成するなら設定(例 node build.mjs/出力先を assets.directory に合わせる)。ビルド不要でリポジトリに直接 HTML を置くなら空欄でも可(その場合 assets.directory をその置き場所=例 ./public に向ける)。main は残し、GitHub の Web UI で src/index.ts も必ず作成します(Add file → Create new file で、ファイル名に src/index.ts と入力するとフォルダごと作れます)。中身は後述の「D1 サンプル」の src/index.ts をそのまま使えます。この型では「wrangler.jsonc の main」と「実在する src/index.ts」がセットで必要——片方だけだと今回のエラーになります。ローカルで Worker プロジェクトを作成
Cloudflare 公式のスキャフォールドツール(C3)で雛形を生成します。対話プロンプトでテンプレートと TypeScript の利用有無を選ぶと、設定ファイル wrangler.jsonc を含むプロジェクトが作られます。
npm create cloudflare@latest your-app
cd your-app静的ファイル(HTML/CSS/JS)も配信する場合は、アセット用ディレクトリを指定します。
{
"name": "your-app",
"main": "src/index.ts", // Workerコードの入口。静的サイトのみなら main 行は不要(上の型A参照)
"compatibility_date": "YYYY-MM-DD", // 作成日を入れる
"assets": { "directory": "./public" }
}ローカル確認は npx wrangler dev で行えます。
Git を初期化し、GitHub へ push
GitHub 側で空のリポジトリを1つ作成しておきます。
git init
git add -A
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-account/your-repo.git
git push -u origin main.env / .dev.vars をコミットしないこと。.gitignore に .dev.vars* と .env* を追加しておきます。Cloudflare と GitHub を連携する
Cloudflare ダッシュボードで Workers & Pages → Create application → Import a repository の順に進み、Git アカウントを選択します。初回は GitHub アプリ「Cloudflare Workers and Pages」の認可を求められます。続いてデプロイ対象のリポジトリを選択します。
設定ファイルが無いリポジトリを接続した場合、Cloudflare がフレームワークを自動検出し、設定を追加する Pull Request を自動作成します。C3 で雛形を作っていれば設定済みのため不要です。
ビルド / デプロイ設定
接続時の設定画面で以下を指定します。
| 設定項目 | 値の例 | 備考 |
|---|---|---|
| Production branch | main | このブランチへの push がトリガー |
| Build command | npm run build | ビルド不要なら空欄でも可 |
| Deploy command | npx wrangler deploy | 既定値のまま使えることが多い |
Save and Deploy を選択すると、初回ビルドとデプロイが走ります。
初回デプロイを確認
完了すると https://your-app.<your-subdomain>.workers.dev の URL が払い出されます。ブラウザでアクセスして動作を確認します。ビルドログは Deployments タブ最下部の View build history から見られます。
独自ドメインを割り当てる
「独自ドメインで即確認」の核心です。対象ドメインが Cloudflare のゾーン配下にあることが前提です。対象の Worker を開き、Settings → Domains & Routes → Add → Custom Domain から使用するホスト名(例:app.example.com)を入力して保存します。
Cloudflare が必要な DNS レコードと TLS 証明書を自動で発行・設定します。以降、このドメインは常に最新の本番デプロイを指すため、push → ビルド完了 → 自動反映のループが完成します。
Daily flow
日常の運用フロー
構築後は、これだけで本番が更新されます。デプロイの成否は GitHub のコミット横のチェックから確認できます。
# ローカルでコードを編集
$ git add -A
$ git commit -m "Update layout"
$ git push
# → 数十秒〜数分後、独自ドメインに自動反映
Operate & Recover
ロールバックと観測
「壊れてもすぐ戻せる」「何が起きているか見える」の2つが揃うと、push が怖くなくなります。GitOps 運用の安心材料として最初に押さえておきたい部分です。
壊れたら:即時ロールバック
デプロイは世代管理されており、以前の正常なバージョンへ数秒で切り戻せます。git revert を push してビルド完了を待つより速いので、「まず戻す → 落ち着いて原因調査」が定石です。
npx wrangler rollback
# または:ダッシュボード → 対象 Worker → Deployments
# → 戻したいデプロイの「…」→ Rollbackビルドの失敗は本番を壊さない
Workers Builds では、ビルドが失敗しても本番は「最後に成功したデプロイ」を配信し続けます。エラー画面に変わることはありません。裏を返すと、「push したのに本番が変わらない」ときの最有力容疑者はビルド失敗です。対象 Worker の Deployments → View build history でログを確認してください。
観測:ログとメトリクス
開発中の「本番で何が起きているか分からない」を避けるために、次の2つを用意しておきます。
| 手段 | 使い方 | 向いている場面 |
|---|---|---|
| リアルタイムログ | npx wrangler tail で本番の console.log や例外をターミナルへストリーム表示 | いま起きている問題の調査 |
| Workers Logs(保存ログ) | wrangler.jsonc に "observability": { "enabled": true } を追加すると、ダッシュボードでログの検索・集計が可能に | 過去にさかのぼる調査・エラー率の把握 |
| メトリクス | ダッシュボードの Worker 概要(リクエスト数・エラー・CPU 時間) | 傾向の監視・無料枠の消費確認 |
Optional
環境変数・Secrets・データベース
Worker に値を渡す3つの方法
| 種類 | 中身 | Git に載るか | 用途 |
|---|---|---|---|
| vars(変数) | 平文の設定値 | 載る | API ホスト名など、秘密でない設定 |
| Secrets | 暗号化された秘密文字列 | 載らない | パスワード・API キー・外部 DB の接続文字列 |
| Bindings | Cloudflare リソースへの参照 | 参照情報は載る | D1・KV・R2 などへの接続 |
機密値はコードや設定ファイルに書かず、Secrets として登録します。コードからは環境変数として読めます。ローカル開発用の値は .dev.vars に記述し、必ず Git 管理から除外します。
npx wrangler secret put SECRET_NAME
# → 値の入力を求められる。値はリポジトリに残らないデータベース(D1)を使う
リレーショナル DB が必要なら、Cloudflare 純正の D1(サーバーレス SQLite)が最も手軽です。DB は Secrets ではなく バインディングで接続するため、パスワード管理は不要です。
npx wrangler d1 create your-db出力された database_id を wrangler.jsonc に追記します(ID は秘密情報ではないため Git に載せて問題ありません)。
{
"d1_databases": [
{ "binding": "DB", "database_name": "your-db", "database_id": "..." }
]
}D1 以外の選択肢(バインディング/トリガー早見表)
データの形やアクセスパターンによっては、D1 より適したリソースがあります。いずれも接続方法は同じ「バインディング」方式(+Cron はトリガー設定)で、wrangler.jsonc に書いて push すれば有効になります。
| リソース | 何に使う | 特徴・向いている場面 |
|---|---|---|
| D1 | リレーショナル DB(SQLite) | 正規化されたデータ・SQL で集計したいとき。まず第一候補 |
| KV | キー・バリューストア | 設定値・キャッシュ・セッション等。読み取りが速く世界中に複製される。書き込み反映は結果整合(数十秒の遅延あり得る) |
| R2 | オブジェクトストレージ(S3 互換) | 画像・動画・大きなファイル。下り転送料(egress)が無料なのが最大の強み |
| Durable Objects | 強整合な状態+WebSocket | チャット・共同編集・カウンタ等、「1つの実体に順番に処理させたい」場面 |
| Queues | 非同期ジョブキュー | 重い処理を後回しにして、リクエストへは即応答したいとき |
| Cron Triggers | 定期実行 | "triggers": { "crons": ["0 3 * * *"] } のように書くと、指定時刻に Worker の scheduled ハンドラが走る。バッチ・定期チェックに |
Hands-on · D1 sample
サンプル:D1 で動く最小アプリを公開する
アクセスカウンターを例に、D1 を使う Worker を push だけで公開するところまで通します。テーブル作成もコード内で行うので、ローカル環境が無くてもブラウザ操作だけで完結できます。
① D1 データベース=ダッシュボードで作成(Storage & Databases → D1 → Create)→
database_id を控える② wrangler.jsonc と src/index.ts=GitHub の Web UI で作成(前章の型B。
main と実在する src/index.ts はセット)③ テーブル=コード内の
CREATE TABLE IF NOT EXISTS で自動作成、または ダッシュボードの D1 → Console に SQL を貼って実行④ デプロイ=push すれば Workers Builds がクラウドでビルド&デプロイ(
wrangler d1 create や wrangler deploy を端末で打つ必要はない)端末に Node.js も wrangler も不要。CLI を使う手順は「ローカルがある人向けの近道」にすぎません。
D1 データベースを作る
CLI でもダッシュボードでも作れます。出力(または詳細画面)の database_id を控えます。
npx wrangler d1 create demo-db2つのファイルをリポジトリに置く
ローカルがあれば作成、無ければ GitHub の Web UI(Add file → Create new file) でそのまま作れます。database_id は手順1の値に置き換えます。
{
"name": "d1-counter",
"main": "src/index.ts",
"compatibility_date": "2025-01-01",
"d1_databases": [
{ "binding": "DB", "database_name": "demo-db", "database_id": "<手順1のID>" }
]
}export default {
async fetch(request, env) {
// 初回だけテーブルを用意(無ければ作る)
await env.DB.prepare(
"CREATE TABLE IF NOT EXISTS counter (id INTEGER PRIMARY KEY, hits INTEGER NOT NULL)"
).run();
// アクセスのたびに +1(1行目が無ければ作る)
await env.DB.prepare(
"INSERT INTO counter (id, hits) VALUES (1, 1) ON CONFLICT(id) DO UPDATE SET hits = hits + 1"
).run();
const row = await env.DB.prepare("SELECT hits FROM counter WHERE id = 1").first();
return new Response(
`<!doctype html><meta charset=utf-8><h1>訪問数: ${row.hits}</h1>`,
{ headers: { "content-type": "text/html; charset=utf-8" } }
);
}
};"binding": "DB" の名前が、コードの env.DB と一致している必要があります。push してデプロイ
変更をコミットして push します(GitHub Web UI なら「Commit changes」)。接続済みであれば Workers Builds がクラウドでビルドし、自動デプロイされます。端末でのビルドは不要です。
git add -A && git commit -m "Add D1 counter" && git push動作を確認
公開 URL(独自ドメイン、または *.workers.dev)にアクセスするたびに、D1 に保存されたカウントが増えていれば成功です。再デプロイしてもカウントは保持されます。
schema.sql にまとめ、ローカルがあれば npx wrangler d1 execute demo-db --remote --file=./schema.sql、ローカル無しならダッシュボードの D1 → Console に SQL を貼って実行し、コードはクエリだけに集中させるのがおすすめです(どちらでも同じ本番DBに適用されます)。Pricing
料金の目安
課金されるのは主に Worker(サーバーコード)が実行されたときです。静的アセットの配信や独自ドメイン・DNS・TLS は無料のため、静的サイトや小規模アプリなら ほぼ無料で運用できます。
| プラン | 月額 | 含まれる目安 | 向き |
|---|---|---|---|
| Workers Free | $0 | 100,000 リクエスト/日、1 リクエストあたりの CPU 時間に上限 | 個人・検証・小規模 |
| Workers Paid | $5〜 | 1,000万リクエスト/月込み(超過は約 $0.30 / 100万)+ CPU 時間の枠 | 本番・規模拡大 |
静的アセット配信
HTML/CSS/JS など静的ファイルへのリクエストは無料・無制限。サーバーコードを実行しなければ課金対象になりません。
ドメイン・DNS・TLS
Cloudflare ゾーン配下なら、独自ドメインの割り当て・DNS・TLS 証明書はいずれも無料です。
D1 / KV / R2
データベースやストレージは各サービスごとに無料枠があります(例:D1 は 5GB・読み取り500万行/日)。超過分のみ課金。
Environments
ステージング環境の分け方
本番に影響を与えずに検証するには、本番(production)とステージング(staging)を分けます。手軽さ重視と分離重視で、代表的な2通りがあります。
方法A:ブランチのプレビューを使う(手軽)
Workers Builds は、本番ブランチ以外への push に対してプレビューデプロイを作成し、専用のプレビュー URL を払い出します。PR やお試しの確認に向き、追加設定はほぼ不要です。
| 環境 | ブランチ | URL | 用途 |
|---|---|---|---|
| 本番 | main | 独自ドメイン | 公開版 |
| ステージング | staging など | プレビュー URL | 本番反映前の検証 |
npx wrangler versions upload が実行され、本番とは別のプレビュー専用 URL が払い出されます(ビルド履歴やコミットのチェックから辿れます)。本番の独自ドメインには一切影響しません。方法B:wrangler の environments で分離(明確)
wrangler.jsonc に環境を定義すると、別名の Worker として独立してデプロイできます。名前・変数・バインディング・ドメイン・Secrets を環境ごとに分けられます。
{
"name": "your-app",
"main": "src/index.ts",
"env": {
"staging": {
"name": "your-app-staging",
"vars": { "ENVIRONMENT": "staging" }
}
}
}デプロイ時に環境を指定します。
npx wrangler deploy --env staging
# → your-app-staging として独立してデプロイされるnpx wrangler secret put NAME --env staging で登録し、D1 などのデータベースも staging 用を別に作成してバインドします。こうすれば、検証で本番データを汚しません。Troubleshooting
動作確認とトラブルシュート
| 症状 | 確認ポイント |
|---|---|
| push してもデプロイされない | push 先ブランチが Production branch と一致しているか |
| push したのに本番が変わらない(エラー画面も出ない) | 最有力はビルド失敗。失敗時は最後に成功したデプロイを配信し続けるため、見た目では気付けない。Deployments → View build history でログを確認 |
| ビルドが失敗する | Deployments → ビルドログでエラー内容を確認。ビルドコマンドが非ゼロ終了(テスト・チェックの失敗含む)していないか |
ビルドの npm clean-install が失敗する | package-lock.json をコミットしているか(Workers Builds はロックファイルを前提に依存を復元する) |
| ローカルと Node のバージョンが違う | ビルド設定の環境変数に NODE_VERSION(例:20)を追加するか、.nvmrc を置く |
| デプロイ成功なのに表示が古い | ブラウザキャッシュ。ハードリロード(Shift+再読み込み)や別端末で確認 |
| 独自ドメインで表示されない | ドメインが Cloudflare ゾーン配下か/DNS 伝播待ち/ドメインが意図した Worker に紐付いているか |
| Secrets が読めない | wrangler secret put で登録済みか、名前が一致しているか。環境(--env)ごとに別登録が必要な点にも注意 |
Cheat sheet
wrangler CLI チートシート
日常運用は push だけで回りますが、調査・復旧・初期設定で使う wrangler コマンドをまとめておきます。すべて npx wrangler ... で実行できます(インストール不要)。
| コマンド | 何をするか |
|---|---|
npx wrangler dev | ローカルで Worker を起動(http://localhost:8787)。D1 等はローカル用の疑似リソースが使われる |
npx wrangler deploy | 手動で本番デプロイ(通常は push に任せるので出番は少ない) |
npx wrangler versions upload | デプロイせずにプレビュー版をアップロードし、プレビュー URL を得る |
npx wrangler rollback | 以前のデプロイへ即時切り戻し |
npx wrangler tail | 本番のログ(console.log・例外)をリアルタイム表示 |
npx wrangler secret put NAME | Secret を登録(--env staging で環境別) |
npx wrangler d1 create NAME | D1 データベースを作成 |
npx wrangler d1 execute DB --remote --file=schema.sql | 本番 D1 に SQL を適用(--remote を忘れるとローカルに当たる) |
npx wrangler whoami | どのアカウントにログイン中か確認 |
Best practices
セキュリティのベストプラクティス
- GitHub アプリのアクセス範囲は「Only select repositories」で対象リポジトリのみに限定する
- 機密値(API キー・トークン・DB 認証情報)はソースコードや
wrangler.jsoncに絶対に書かず、wrangler secret putで登録する .dev.vars/.envは.gitignoreに追加し、コミットしない- 本番・ステージング・開発で別々の値を使う場合は、環境(environments)ごとに Secrets を分離する
Appendix
代替方式:GitHub Actions を使う
CI 内でテストや Lint を挟みたい場合は、Workers Builds の代わりに GitHub Actions + 公式アクションでデプロイできます。この場合は Cloudflare の API トークンを GitHub Secrets に登録する必要があります。
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Deploy
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}まずは Workers Builds で運用を始め、CI に独自処理を足したくなった段階で Actions へ移行するのが無理のない流れです。