Cloudflare Workersで静的サイトを独自ドメインで公開

AIで作った静的サイトを、Cloudflare Workers の無料プランで独自ドメインに公開した手順です。wrangler.toml、ログイン、デプロイ、www と http の転送まで、つまずいた点と確かめ方つきでまとめます。

AI(Claude)が書き、運営者が確認して公開した記事です。分担と確かめたもの →

目次

AIの助けを借りて作ったサイトを、自分のドメイン(自分の名前.com のような住所)で公開する手順です。このサイト Alice in Sandbox は、2026年10月21日〜22日に、Cloudflare Workers の静的アセットという仕組みで aliceinsandbox.com に公開しました。そのときの設定ファイル、打ったコマンド、つまずいた点をそのまま載せます。

HTML のファイル一式ができていて、それを無料で自分のドメインで出したい人向けです。サーバーを借りるか無料で済ませるかをまだ決めていない人は、先にAIで作ったものを無料で公開する方法を読んでください。

仕様と上限は2026年10月22日時点の公式ドキュメントで確かめたもので、変わることがあります。

先に結論:手順は6つ

表: 先に結論:手順は6つ
順 やること 誰が・どこで
1 wrangler.toml(設定ファイル)を書く AI(Claude)が作成・点検
2 npx wrangler login でログインする 運営者がターミナルで
3 npx wrangler deploy で公開する 運営者がターミナルで
4 ドメインを取り、wrangler.toml に足して再デプロイ 運営者が取得・AI(Claude)が設定を追加
5 www つきの住所を、www なしへ転送する 運営者がダッシュボードで
6 http を https へ転送する(Always Use HTTPS) 運営者がダッシュボードで

つまずいたのは、ログイン(API トークンの環境変数が設定されていた)、設定ファイルの書く位置、http のまま表示されていた件の3か所です。原因と直し方は、手順のあとの「つまずいたこと」にあります。

必要なもの

  • 公開するファイル一式: このサイトは Python のスクリプトで Markdown から HTML を作り、public/ フォルダに出力しています。
  • Cloudflare のアカウント: Workers の Free プランで公開できます。
  • Node.js: npx コマンドで wrangler(Cloudflare の公式のコマンドラインツール)を動かすのに必要です。
  • 独自ドメイン: Workers の Custom Domains を使うには、ドメインを Cloudflare で管理している必要があります。Cloudflare 上で有効なゾーンになっている状態です(公式: Custom Domains)。

Free プランの上限(2026年10月22日時点)

公式の上限のページによると、静的アセットの上限は次のとおりです。

表: Free プランの上限(2026年10月22日時点)
項目 Workers Free Workers Paid
1バージョンあたりのファイル数 20,000 100,000
1ファイルの大きさ 25MiB(約26MB) 25MiB

静的アセットへのリクエストは「無料・無制限」と公式で案内されています。Worker のプログラムを書かず、ファイルを配るだけなら、リクエスト数の上限を気にせずに済みます。

ドメインの取り方

運営者は、2026年10月21日に Cloudflare Registrar(Cloudflare のドメイン販売)で aliceinsandbox.com を取得しました。Cloudflare Registrar は、レジストリ(ドメインの元締め)に払う卸値で売り、上乗せをしないと公式で説明しています。更新も上乗せなしの卸値です。

.com の金額は、2026年10月22日時点で公式ページの本文に書かれていないため、この記事には載せません。取得する前に、Cloudflare のドメイン検索の画面で確かめてください。名前の決め方と、ほかの会社の更新料との比べ方はサイト名とドメインの決め方にまとめています。

手順1:wrangler.toml を書く

wrangler.toml は、wrangler に「何を・どこへ公開するか」を伝える設定ファイルです。サイトのフォルダの一番上(public/ と同じ階層)に置きます。AI(Claude)が書いた、このサイトの最終形がこれです。

toml
name = "aliceinsandbox"
compatibility_date = "2026-09-30"

routes = [
  { pattern = "aliceinsandbox.com", custom_domain = true },
]
workers_dev = false
preview_urls = false

[assets]
directory = "./public"
html_handling = "auto-trailing-slash"
not_found_handling = "404-page"

1行ずつの意味は次のとおりです(公式: 設定ファイルの説明)。

表: 手順1:wrangler.toml を書く
行 意味
name Worker の名前。ダッシュボードにこの名前で出る
compatibility_date 必須。どの版の Workers の動作に合わせるかを日付で決める
routes 公開する住所。custom_domain = true で独自ドメインとして扱う
workers_dev = false 〇〇.workers.dev の住所では公開しない
preview_urls = false 版ごとの確認用 URL(Preview URLs)を出さない
[assets] の directory 公開するファイルのフォルダ
html_handling URL の末尾の / の扱い
not_found_handling 存在しないページを開いたときの扱い

workers_dev と preview_urls を false にしたのは、同じ中身を workers.dev の住所でも出すと、検索エンジンから見て同じページが2つの住所にあることになるからです。

html_handling = "auto-trailing-slash" は既定の値で、about/index.html のようなフォルダの中の index.html は /about/、about.html のようなファイルは /about で表示されます。もう一方の形で開くと、307 で正しい形に転送されます(公式: HTML handling)。

not_found_handling = "404-page" にすると、ファイルが無い住所を開いたとき、いちばん近い 404.html を状態コード 404 で返します(公式: 404 ページ)。既定の "none" のままだと、自分で作った 404 ページは出ません。public/404.html を用意しておきます。

⚠️ ドメインを取る前に初回デプロイをするなら、routes から preview_urls までの5行は書かず、ドメインを取ってから足します(手順4)。workers_dev = false を先に書くと、workers.dev の住所でも公開されません。

手順2:wrangler にログインする

ターミナル(Windows なら PowerShell)を開き、wrangler.toml のあるフォルダで次を実行します。

powershell
npx wrangler login

初めて実行すると、wrangler をインストールしてよいかを聞かれます。このサイトのときは wrangler 4.151.3 で、y で進めました。続いてブラウザが開き、Cloudflare のアカウントでアクセスを許可します(公式: wrangler login)。

ログインできたかは、次のコマンドで確かめます。ログイン中のアカウントが表示されます。

powershell
npx wrangler whoami

運営者の環境では、ここでエラーが出ました。原因と直し方は「つまずいたこと」の1つ目にあります。

手順3:初回デプロイ

powershell
npx wrangler deploy

成功すると、送ったファイル数が表示されます。このサイトの初回は Uploaded 512 files でした。workers_dev を書いていない状態なら、https://<Worker名>.<アカウントのサブドメイン>.workers.dev の住所で公開されます。

デプロイの前に、AI(Claude)が3つを点検しました。

  • 下書きや記入漏れのページが残っていないか(ビルドの厳格モードで確かめた)
  • リンク切れが無いか(外部リンクの切れ1件と、移動していた20件を直した)
  • 公開するファイルに個人情報が混ざっていないか

⚠️ このサイトは、サイトの URL の設定を先に aliceinsandbox.com にしてから、ドメインを取る前に workers.dev へ初回デプロイしました。そのため、各ページの canonical(「このページの本来の住所」を検索エンジンに伝えるタグ)と sitemap が、まだ取っていないドメインを指していました。この状態では、検索エンジンは「本物は別のドメインにある」と受け取ります。workers.dev で長く公開しておくつもりがないなら、ドメインを先に取ってから初回デプロイするほうが、この食い違いが起きません。

手順4:独自ドメインをつなぐ

ドメインを取ったら、wrangler.toml の [assets] より上に、次の5行を足します。

toml
routes = [
  { pattern = "aliceinsandbox.com", custom_domain = true },
]
workers_dev = false
preview_urls = false

pattern には自分のドメインを書きます。足したら、もう一度デプロイします。

powershell
npx wrangler deploy

運営者がデプロイすると、https://aliceinsandbox.com でサイトが表示されました。DNS のレコード(ドメインとサーバーを結ぶ設定)と証明書(https に要るもの)は自動で作られ、ダッシュボードで DNS を手で足す作業はありませんでした。公式の説明でも、Custom Domains は DNS レコードと証明書を Cloudflare が作るとされています。

公式の説明では、次の2点も確かめておきます。

  • そのホスト名に CNAME レコードがすでにあると、Custom Domain は作れない
  • ワイルドカード(*.example.com のような書き方)は使えない

workers_dev = false にしたので、このデプロイのあと workers.dev の住所は 404 になりました。

手順5:www つきの住所を転送する

ここまでで https://aliceinsandbox.com は表示されますが、https://www.aliceinsandbox.com/ はつながりませんでした。www の DNS レコードが無いためです。公式の説明でも、example.com の Worker は www.example.com へのリクエストを受け取らないとされています。

運営者は Cloudflare のダッシュボードで、次の2つを設定しました。

DNS に www のレコードを足す

DNS のページで、次のレコードを追加します。

表: DNS に www のレコードを足す
項目 値
タイプ AAAA
名前 www
IPv6 アドレス 100::
プロキシ Proxied(オレンジの雲)

100:: は、どこにもつながらないダミーの住所です。リクエストは Cloudflare の中で転送されるので、行き先のサーバーは要りません。公式の Custom Domains のページでは、同じ用途の例として A レコードの 192.0.2.0 が挙げられています。どちらを使う場合も、Proxied にしておくことが条件です。DNS only(灰色の雲)にすると、次の転送ルールが働きません(公式: Single Redirects の作り方)。

Redirect Rule のテンプレートを使う

Rules の Overview から Create rule → Redirect Rule と進み、テンプレートの「Redirect from WWW to Root」を選びます。中身は次のとおりです(公式: www から root への転送)。

表: Redirect Rule のテンプレートを使う
項目 値
条件 Wildcard pattern・Request URL https://www.*
転送先 https://${1}
状態コード 301
クエリ文字列を保持 ON

${1} には、* に当たった部分(ドメインの残りとパス)が入ります。AI(Claude)が curl で確かめると、https://www.aliceinsandbox.com/make/?a=1 は 301 で https://aliceinsandbox.com/make/?a=1 に転送されました。パスと ?a=1 も引き継がれています。

手順6:http を https に転送する

SSL/TLS → Edge Certificates を開き、Always Use HTTPS を ON にします。すべての http:// のリクエストが https:// に転送されます。Free プランで使える機能です(公式: Always Use HTTPS)。

SSL/TLS の暗号化モードが Off だと、この項目は表示されません。

この手順が要る理由は、次の「つまずいたこと」の3つ目にあります。

HSTS はまだ ON にしていない

HSTS は、「このサイトは https でしか開かない」とブラウザに覚えさせる設定です。Cloudflare の SSL/TLS → Edge Certificates で ON にできます。

公式の注意書きでは、HSTS を有効にしたあとで HTTPS をやめると、Max Age(覚えさせる期間・1〜12か月)のあいだサイトに入れなくなります。無効に戻しても、すでに覚えたブラウザは期間が終わるまで https を強制し続けます(公式: HSTS)。設定を間違えたときに戻しにくいので、このサイトではまだ ON にしていません。サイトが安定してから検討します。

つまずいたこと

1. ログインが API トークンの環境変数に止められた

npx wrangler login を実行すると、次のエラーが出ました。

AIに送る文
X [ERROR] You are logged in with an API Token. Unset the CLOUDFLARE_API_TOKEN in the environment to log in via OAuth.

npx wrangler whoami も Failed to automatically retrieve account IDs for the logged in user. と出て、アカウントを確認できませんでした。メッセージには、トークンの権限不足か期限切れの可能性がある、とも表示されました。

AI(Claude)が原因を調べると、Windows のユーザー環境変数に CLOUDFLARE_API_TOKEN が設定されていました。wrangler は、この環境変数があるとブラウザでのログイン(OAuth)よりそちらを優先します。公式の説明でも、環境変数は保存済みのログイン情報より優先されるとされています。

ほかのツールがその変数を使っている場合、変数そのものを消すと、そちらが動かなくなります。そこで、その PowerShell の窓の中だけ変数を外してからログインしました。

powershell
Remove-Item Env:CLOUDFLARE_API_TOKEN
npx wrangler login
npx wrangler whoami
npx wrangler deploy

新しい窓を開くと変数は戻るので、デプロイのたびに、その窓で1行目を実行します。

2. TOML の表の位置で、設定が assets の中に入った

AI(Claude)が最初に routes・workers_dev・preview_urls を足したとき、ファイルの末尾に書きました。TOML という書式では、[assets] のような見出し(表)のあとに書いたキーは、次の見出しが来るまで全部その表の中に入ります。末尾に足した3つは、assets.routes のように [assets] の一部として読まれる状態でした。

Python の tomllib(TOML を読む標準の部品。Python 3.11 以降)で読み直して気づき、[assets] より上に移しました。手で確かめるなら、次のように読んで、routes が一番外側にあるかを見ます。

powershell
python -c "import tomllib, pprint; pprint.pprint(tomllib.load(open('wrangler.toml', 'rb')))"

出力の一番外側に 'routes'・'workers_dev'・'preview_urls' があり、'assets' の中に入っていなければ正しい位置です。

3. http で開くと暗号化なしで表示されていた

公開後に AI(Claude)が curl で確かめると、次の2つが見つかりました。

  • http://aliceinsandbox.com/ が 200 で、暗号化なしのまま表示された
  • http://www.aliceinsandbox.com/start/ が 522(Cloudflare から先につながらないときのエラー)になった

原因は、手順5の Redirect Rule が https://www.* だけを対象にしていたことです。公式の説明にも、http のリクエストと www 以外の住所は変更しないと書かれています。http を https に送る設定が、どこにもありませんでした。

手順6の Always Use HTTPS を ON にすると、次のようになりました。

  • http://aliceinsandbox.com/ → 301 → https://aliceinsandbox.com/
  • http://www.aliceinsandbox.com/start/ → 301 → https://www.aliceinsandbox.com/start/ → 301 → https://aliceinsandbox.com/start/(2回の転送のあと 200)

www の転送を設定したら、http:// の住所でも開いてみるのが確かめ方のこつです。

公開後の確かめ方

curl で状態コードを見る

AI(Claude)は curl で、住所ごとの状態コード(200=表示できた、301=転送、404=ページが無い)を確かめました。Windows の PowerShell では curl ではなく curl.exe と打ちます。

powershell
# 状態コードだけを表示する
curl.exe -s -o NUL -w "%{http_code}`n" https://aliceinsandbox.com/

# 転送先を確かめる(-I でヘッダーだけ、-L で転送をたどる)
curl.exe -sIL http://www.aliceinsandbox.com/start/

このサイトで確かめた住所と結果です。

表: curl で状態コードを見る
住所 結果
トップ・/make/・/robots.txt・/sitemap.xml 200
存在しないページ 404(自分の 404 ページが表示された)
workers.dev の住所 404
https://www.〜/make/?a=1 301 → https://aliceinsandbox.com/make/?a=1
http://aliceinsandbox.com/ 301 → https
http://www.〜/start/ 301 → 301 → 200

自分のドメインで試すときは、少なくとも「https の root」「https の www」「http の root」「http の www」「存在しないページ」の5つを見ます。

ブラウザで見る

最後は、ブラウザで同じ住所を開き、www なしの https:// の住所に落ち着くか、404 ページに自分のデザインが出るかを目で確かめます。

検索エンジンにサイトを知らせる設定と、アクセス解析を入れるときのプライバシーポリシーの書き方は、GA4 と Search Console の入れ方とプライバシーポリシーにあります。タブのアイコンや、SNS でシェアされたときの画像はファビコンとシェア画像の作り方にまとめています。

まとめ

  • Cloudflare Workers の静的アセットなら、Free プランで独自ドメインのサイトを公開できる。上限は1バージョン20,000ファイル・1ファイル25MiB(2026年10月22日時点)
  • wrangler.toml の routes に custom_domain = true を書いてデプロイすると、DNS レコードと証明書は自動で作られた
  • routes・workers_dev・preview_urls は [assets] より上に書く。下に書くと [assets] の中に入る
  • ログインが止まったら、CLOUDFLARE_API_TOKEN の環境変数が設定されていないかを見る
  • www は、Proxied の DNS レコードと Redirect Rule のテンプレートで root へ転送する。http は Always Use HTTPS で https へ送る
  • 公開後は curl で、http/https と www あり/なしの組み合わせを全部確かめる

作業の前に、記事中のリンクから公式ドキュメントの最新の内容を確かめてください。

この記事について

この記事でやった人

やったこと誰が
wrangler.toml を書き、デプロイ前に下書き・リンク切れ・個人情報の混入を点検するAI(Claude)
npx wrangler login と npx wrangler deploy をターミナルで実行する運営者
aliceinsandbox.com を Cloudflare Registrar で取得する運営者
www の DNS レコード・Redirect Rule・Always Use HTTPS をダッシュボードで設定する運営者
ログインのエラー(API トークンの環境変数)と TOML の書く位置の原因を調べて直すAI(Claude)
公開後に curl で状態コードと転送を確かめるAI(Claude)
記事の目視確認と公開の判断運営者

料金や仕様は変わることがあります。検証日より後の変更は、各サービスの公式情報で確かめてください。