CHP-002

サイト構築の実施記録

2026-05-20 に実施した https://lunelukkio.com 構築プロジェクトの全工程の振り返り。
ゴール「AI で作成した HTML を本人だけが見られる無料サイトとして公開する」を完全達成。

目次
  1. プロジェクト概要と達成状態
  2. タイムライン(全 6 フェーズ)
  3. 各フェーズの詳細
  4. 認証フローの詳細
  5. 遭遇した課題と解決
  6. コスト構造
  7. 完成後の運用
  8. 学んだこと

1. プロジェクト概要と達成状態

名前.com で取得済みのドメイン lunelukkio.com を使い、AI で作成した HTML 教科書・学習ノートを本人だけが閲覧できる Web サイトとして公開した。実装は GitHub と Cloudflare の無料枠で完結し、ランニングコストはドメイン年額のみ。

項目達成内容
公開 URLhttps://lunelukkio.com
認証Google ログイン経由で lunelukkio@gmail.com のみ閲覧可
HTTPSCloudflare が自動発行・自動更新
デプロイgit push 後 1〜2 分で自動反映
月額ランニング0 円(ドメイン年額のみ)
正本データGitHub リポジトリ lunelukkio/lunelukkio-site (Private)

2. タイムライン(全 6 フェーズ)

計画書 plan.md の Phase 1〜6 を順に実施した。

Phase 1 GitHub リポジトリ作成 Private Phase 2 ローカル準備 初期 HTML push SSH 認証含む Phase 3 DNS 移管 名前.com → CF NS 変更 Phase 4 Pages デプロイ GitHub 連携 仮 URL 発行 Phase 5 独自ドメイン 接続 + HTTPS CNAME 自動 Phase 6 Cloudflare Access Google ログイン認証 本人のみ許可 準備(コード側) 配信基盤構築(Cloudflare) アクセス制御(認証) 達成状態 https://lunelukkio.com で Google ログイン経由、本人だけが教科書サイトを閲覧可能(無料・自動デプロイ・HTTPS)
図1. 全フェーズの俯瞰図とゴール

3. 各フェーズの詳細

Phase 1GitHub リポジトリ作成

HTML コンテンツの正本を保管する場所を用意した。

項目設定
リポジトリ名lunelukkio-site
公開設定Private(本人と Cloudflare のみアクセス可)
初期化README 自動生成

狙い: 「設計時の意思決定」で議論したとおり、教科書と学習ノートを一つのリポジトリに統合(案 X、フラット構造)。

Phase 2ローカル準備と初期 HTML 配置

各 PC で作業できるよう SSH 鍵を設定し、リポジトリを clone、最小限の HTML を配置した。

# 1. SSH config を設定(macOS Keychain 連携)
~/.ssh/config:
Host github.com
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

# 2. clone
cd ~/Documents
git clone git@github.com:lunelukkio/lunelukkio-site.git

# 3. 初期ファイル配置
- index.html (ルート目次)
- README.md
- assets/style.css (共通スタイル)
- claude-html-project/index.html
- claude-html-project/chp-001.html (既存からの移行)

# 4. 初回コミット & push
git add . && git commit -m "初期サイト構造を追加" && git push

※ この段階で SSH 鍵問題に遭遇(後述)。

Phase 3Cloudflare アカウントと DNS 移管

名前.com で管理されていたドメインの DNS を Cloudflare に引き継いだ。

  1. Cloudflare アカウント作成(無料)
  2. 「Add a site」で lunelukkio.com を追加
  3. Cloudflare が 2 つのネームサーバーを提示
  4. 名前.com Navi で「ネームサーバー変更」→ Cloudflare の 2 つを設定
  5. 数分〜数時間で DNS 反映、Cloudflare ダッシュボードが「Active」に変化

確認時のチェックポイント: DNS Setup = Full(Cloudflare が完全管理)、Registrar = Onamae.com(登録元はそのまま)。

Phase 4Cloudflare Pages デプロイ

GitHub リポジトリと Cloudflare Pages を連携させ、push のたびに自動デプロイされる体制を作った。

設定項目
Project namelunelukkio-site
Production branchmain
Framework presetNone(素の HTML)
Build command空欄(ビルド不要)
Build output directory/(リポジトリ直下)

デプロイ成功すると Cloudflare が仮 URL lunelukkio-site.pages.dev を発行し、サイトが閲覧可能になった。

Phase 5独自ドメイン接続

Cloudflare Pages のプロジェクトに lunelukkio.com をカスタムドメインとして紐づけた。

  1. Pages プロジェクトの「Custom domains」→「Set up a domain」
  2. ドメイン名 lunelukkio.com を入力
  3. Cloudflare が CNAME レコードを自動生成(@ → lunelukkio-site.pages.dev
  4. 「Activate domain」で確定 → 「Verifying」を経て「Active」
  5. SSL 証明書は Cloudflare が自動発行(5〜15 分)

この時点で https://lunelukkio.com が誰でも閲覧可能になっている(認証はまだ)。

Phase 6Cloudflare Access による認証保護

本人だけが閲覧できる状態にするため、Zero Trust(Cloudflare Access)を有効化し、Google ログインを認証プロバイダーに設定した。

このフェーズが最も手順が多く、3 つのパートに分かれる。

Part A: Cloudflare 側で Google プロバイダー追加を開始

Part B: Google Cloud Console で OAuth クライアント作成

  1. 新規プロジェクト lunelukkio-access 作成
  2. OAuth consent screen 設定(Branding + Audience タブ)
    • App name: lunelukkio-site
    • User support email / Developer contact: lunelukkio@gmail.com
    • Authorized domains: cloudflareaccess.comlunelukkio.com
    • User type: External、Publishing status: Testing
    • Test users に lunelukkio@gmail.com を追加
  3. OAuth 2.0 Client ID 作成(Web application)
    • Authorized redirect URI に Cloudflare の Callback URL を貼り付け
    • Client ID と Client Secret を取得

Part C: Cloudflare に戻って Client ID / Secret を入力 → テスト

アプリケーション登録とポリシー

最終テスト: シークレットウィンドウで https://lunelukkio.com → Google Passkey 認証 → サイト表示。完全動作。

4. 認証フローの詳細

Phase 6 設定後、訪問者のリクエストは以下のように処理される。

訪問者のブラウザ https://lunelukkio.com Cloudflare DNS 名前解決 → Edge IP を返す Cloudflare Edge 最寄り拠点が受信 Cloudflare Access 既にセッション有? → ない: Google へリダイレクト → ある: 通過 Google OAuth accounts.google.com Passkey or パスワード認証 未認証なら callback (認可コード) ポリシー判定 取得した email を確認 == lunelukkio@gmail.com ? 認証情報 Cloudflare Pages HTML 配信 /index.html を返す 許可 403 他人なら 拒否 HTML 配信
図2. 認証フローのシーケンス(初回ログイン時)

2 回目以降は Cloudflare Access のセッション(24 時間有効)が残っているので Google へのリダイレクトはスキップされ、即座に Pages が応答する。

5. 遭遇した課題と解決

計画書通りに進まなかった部分と、その対処を記録する。

課題1: SSH 鍵が既に登録済みエラー("already in use")

状況: GitHub に SSH 公開鍵を登録しようとしたら「Key is already in use」と表示された。一方で ssh -T git@github.com は Permission denied を返す矛盾した状態。

原因の特定:

  1. ローカル鍵の指紋を ssh-keygen -lf ~/.ssh/id_ed25519.pub で取得
  2. GitHub の Settings → SSH keys で同じ指紋が「Macbookair」として既に登録されていることを発見
  3. つまり「同じアカウントに二重登録できない」というエラーだった(別アカウント疑惑は誤解)
  4. Permission denied の真因は ssh-agent に鍵が読み込まれていない(パスフレーズあり + 非対話環境)

解決: 新規鍵は作らず、~/.ssh/config に macOS Keychain 連携を設定:

Host github.com
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

ユーザーがターミナルで一度 clone(パスフレーズ入力)した後は Keychain が記憶し、以降は自動認証。別プロジェクトでの Git 操作にも影響なし。

課題2: Cloudflare Zero Trust の新 UI で「Authentication」が見つからない

状況: 旧ドキュメントの「Settings → Authentication → Login methods」というパスが新 UI に存在しなかった。

解決: 最新の Cloudflare One ドキュメントを WebFetch で取得し、新しいメニューパスを確認:

Zero Trust → Integrations → Identity providers → Add new identity provider

「Reusable components」や「Access controls → Access settings」を探していたが正解は「Integrations」配下だった。

課題3: Google Cloud Console の OAuth consent screen が新 UI

状況: 「OAuth consent screen」ページで User Type 選択画面が出ず、別の概要ダッシュボードに飛ばされた。

原因: Google Cloud Console は OAuth 同意画面を複数タブに分割した新 UI に移行済み:

解決: 各 URL に直接アクセスして順に設定。Authorized domains には Application home page で指定したドメインも追加が必要だったため cloudflareaccess.com + lunelukkio.com の 2 つを登録。

課題4: 「Workers & Pages」メニューがドメイン管理画面で見つからない

状況: Cloudflare のドメイン管理画面(lunelukkio.com 配下)に Pages 設定が無い。

解決: Pages はアカウントレベルの機能なので、ドメイン画面ではなくアカウントトップから入る:

https://dash.cloudflare.com/<account_id>/workers-and-pages

6. コスト構造

サービス別コスト 完全無料ゾーン GitHub Private リポジトリ無制限 Cloudflare DNS 完全無料 Cloudflare Pages 帯域無制限、500 ビルド/月 Cloudflare Access 50 ユーザーまで Google OAuth Google Cloud の無料枠(同意画面・クライアント作成) 有料ゾーン 名前.com ドメイン lunelukkio.com 年額 約 1,500 円 これが唯一の固定費 自動更新 ON 推奨
図3. サービス別コスト(無料枠 vs 有料)
項目無料枠今回の使用状態
Cloudflare Pages ビルド月 500 回月 数回〜数十回余裕
Cloudflare Pages 帯域無制限個人閲覧のみ余裕
Cloudflare Access ユーザー50 人1 人余裕
GitHub Private リポ無制限1 個余裕
HTTPS 証明書無料・自動更新1 ドメイン不要管理
ドメイン年額約 1,500 円/年固定費

7. 完成後の運用

日常運用フロー 1. 編集準備 git pull 最新を取得 2. コンテンツ追加 learn エージェント or 手動 <topic>/<file>.html 作成 3. 確認 ローカルで file:// で開く 表示確認 4. 公開 git add . && commit git push 5. 自動デプロイ Cloudflare Pages 1〜2 分で反映 6. 閲覧 https://lunelukkio.com Google ログインで確認 複数 PC での同期 他の PC で作業する時: git clone → 編集 → push。リモートが正本なので git pull で常に同期
図4. 完成後の日常運用フロー

learn エージェントとの連携

グローバル ~/.claude/agents/learn.md を更新し、保存先を ~/Documents/lunelukkio-site/<topic>/ に固定済み。新しい質問を learn エージェントに投げると、自動的に:

あとは git push すれば https://lunelukkio.com に反映される。

8. 学んだこと

1. UI は変わる、ドキュメントは古びる

Cloudflare も Google Cloud も、計画書を書いた時点と実際の画面でメニューが違った。最新の公式ドキュメントを WebFetch で確認するのが最も確実。

2. SSH 鍵問題の真因を見極める

「Key is already in use」と聞くと別アカウントを疑いがちだが、指紋を照合すれば同一アカウントへの二重登録が判別できる。新規鍵を作る前に既存状況を確認すべし。

3. フラット構造の威力

教科書と学習ノートを textbook/learning/ に分けず、両方を <topic>/ として直下に並べた(案 X)。URL が短くなり、追加が楽。「分類」は後から index で行えば良い。

4. Zero Trust は無料で個人にも使える

「Zero Trust」と聞くと企業向けの印象だが、Cloudflare の Free プランで 50 ユーザーまで使えるので、個人サイトの認証保護に最適。Google OAuth と組み合わせて 30 分で構築できる。

5. Private リポジトリ + Cloudflare Pages の組み合わせ

GitHub Pages では Public にしないと無料で使えないが、Cloudflare Pages なら Private リポジトリ + Free プランで認証付きサイトが組める。これが今回の最重要な技術選択。

6. 「待ち時間に並行作業」で効率化

DNS 反映や SSL 証明書発行は数分〜十数分かかる。その間に次のフェーズの準備(Google Cloud Console セットアップ等)を進めれば全体時間を短縮できる。

関連項目