anoy-share
目的: リンクを知っている人だけが閲覧できる、認証なしの静的ファイル配信基盤。社内資料・クライアント向けブリーフィング・カジュアルな共有などに使う。Google Drive の「リンクを知っている全員」モードの、自前HTML版。
読み手想定: このREADMEは基本的に AI エージェント(Claude など)が文脈を再構築するために読む前提で書いている。人間も読めるが、冗長な背景説明よりは事実の密度を優先している。
前提と設計思想
なぜこれを作ったか
- 毎回 LP を作って Cloudflare Pages にデプロイするほどではないが、URL で共有したい HTML / 画像 / PDF がある
- フォーマットは縦スクロール・モバイルファースト・10〜30分のカジュアル会話で見せる前提(スマホ画面での閲覧が主)
- 認証ゲートを挟むと共有相手が Apple ID / Google アカウントを求められて UX が壊れる
- 一方、検索エンジンに拾われたりルート URL を叩かれて晒されるのも困る
解決策の骨子
- URL 難読化による事実上のアクセス制御
- 各ドキュメントを 12 文字のランダム slug サブディレクトリに入れる(
openssl rand -hex 6) - ルート(
01.anoy8.com/)は空ページを返し、slug を知らない人には何もない場所に見える robots.txtでクローラー除け
- 各ドキュメントを 12 文字のランダム slug サブディレクトリに入れる(
- これは暗号化ではない。slug が漏れれば誰でもアクセスできる。真の機密は置かないこと。
なぜ Cloudflare Pages ではないのか
- Pages 自体は軽くデプロイできる(
wrangler pages deployなら git 不要) - ただし「保存=即反映」の感触が iCloud Drive 経由の構成に劣る
- Mac mini が常時稼働している前提が崩れたら Pages に移す判断もあり得る
アーキテクチャ
[MacBook Air / 他端末]
↓ 編集(iCloud Drive 経由)
[iCloud Drive]
~/Library/Mobile Documents/com~apple~CloudDocs/anoy-share/
↓ 同期(2〜30秒遅延)
[Mac mini: Anoy---Mac-mini---Office-2]
python3 -m http.server 6149 ← anoy-share/public/ を配信
↓
[Cloudflare Tunnel]
01.anoy8.com → localhost:6149
↓
[閲覧者のブラウザ]
サーバー: Mac mini (Anoy---Mac-mini---Office-2) 上で Python 3.x の http.server が port 6149 を LISTEN。
トンネル: Cloudflare Tunnel が 01.anoy8.com を localhost:6149 にマッピング。
ソース真実: iCloud Drive 上の anoy-share/ フォルダ。Mac mini と MacBook Air の両方にダウンロード済(brctl download でピン留め、実体が雲に引き上げられないようにしている)。
ディレクトリ構造
~/Library/Mobile Documents/com~apple~CloudDocs/anoy-share/
├── README.md ← このファイル(配信対象外)
└── public/ ← http.server が配信するのはここだけ
├── index.html ← 空ページ(noindex, nofollow, body空)
├── robots.txt ← Disallow: /
└── c1a0042ae0ea/ ← slug ディレクトリ(1ドキュメント = 1 slug)
├── index.html
└── *.jpg / *.png ← 画像等のアセット
public/index.html が空ページで存在する理由(重要)
- 削除すると
http.serverはディレクトリ一覧を自動生成し、public/以下の slug 名をルートURLで晒す - 空の
<noindex>ページを置くことで、ルート到達者には「何もない」印象を与える - これは機能を持たないファイルではなく、slug を守る安全装置である
public/ の外側(README.md やこの後追加する運用ファイル)は配信対象ではない
http.serverはpublic/だけを cwd として起動しているため、上位ディレクトリは見えない- 運用メモ・launchd plist・TODOリストなどは
public/の外に置くこと
運用フロー
新しいドキュメントを追加する
cd ~/Library/Mobile\ Documents/com~apple~CloudDocs/anoy-share/public
SLUG=$(openssl rand -hex 6)
mkdir "$SLUG"
# ここに index.html や画像を置く
echo "https://01.anoy8.com/$SLUG/"
生成した URL をチームに共有する。
既存ドキュメントを編集する
MacBook Air / Mac mini いずれからでも以下のパスを直接編集すれば、iCloud 経由で Mac mini のサーバーに反映される:
~/Library/Mobile Documents/com~apple~CloudDocs/anoy-share/public/<slug>/index.html
反映には iCloud 同期の遅延(通常 2〜10 秒、最大 30 秒程度)がある。ブラウザ側は Cmd+Shift+R でキャッシュを回避できる。
http.server を起動する / 再起動する
cd ~/Library/Mobile\ Documents/com~apple~CloudDocs/anoy-share/public
nohup python3 -m http.server 6149 > /tmp/anoy-share.log 2>&1 &
disown
既存プロセスを止めるには:
lsof -i :6149 | grep LISTEN # PID 確認
kill <PID>
疎通確認
curl -I http://localhost:6149/<slug>/ # ローカル
curl -I https://01.anoy8.com/<slug>/ # 公開URL
両方 200 OK であれば配信は生きている。
懸念と既知の制約
1. 認証がない URL 難読化のみ。slug が Slack や メールで漏洩すれば外部からアクセス可能。真の機密資料(個人情報・契約書・未公開財務情報など)は置かない。
2. http.server がサーバー再起動で死ぬ(TODO #12)
現在は nohup + disown で起動しているため、シェル終了には耐えるが Mac mini の再起動で消える。launchd plist を用意して常駐化するのが次の課題。
3. iCloud 同期遅延 Dropbox ほど瞬時ではない。「保存したのにブラウザに反映されない」と思ったら数秒〜数十秒待つ。急ぎで反映したいときは Finder の iCloud ステータス(雲アイコン)を確認する。
4. public/index.html を削除しない
削除すると http.server がディレクトリリストを返して slug が晒される。上記「ディレクトリ構造」参照。
5. ポート 6149 / サブドメイン 01.anoy8.com は固定 Cloudflare Tunnel 側の設定と紐付いている。変更するなら Tunnel config も同時更新が必要。
6. ディレクトリリスト無効化が index.html 依存
本来は http.server 側でディレクトリリストを禁止できた方が堅い。Python 標準の http.server ではオプションがないため、将来的に caddy / nginx への置き換えを検討する余地がある。
7. HTTPS は Cloudflare 側のみ Mac mini 側は HTTP。Tunnel を通らないローカル経路(同一LAN内から localhost:6149)は平文。社外には Tunnel 経由でしか出ないので実害はないが、認識として持っておく。
やってはいけないこと
public/直下にドキュメントを置かない(slug ディレクトリに入れること)。直下に置くと短い予測可能な URL で晒される。public/index.htmlに中身を書かない。ルート URL に到達した人に「ここは何もない」と思わせる演出が効いている間は、空で維持する。- Access / 認証を再導入するときは事前検討。過去に Cloudflare Access + Apple Sign-in を試みて詰まった経緯あり(Cloudflare が Apple を IdP としてネイティブサポートしていないため)。必要になったら Google + 長期セッションクッキーか、mTLS / クライアント証明書方式を先に検討する。
- 真の機密は置かない。これは繰り返しになるが、URL 難読化は認証ではない。
関連情報
- Cloudflare Zero Trust ダッシュボード: https://one.dash.cloudflare.com/
- Cloudflare Tunnel 設定: Mac mini の
cloudflared設定ファイル(場所は運用者に確認) - 現行 slug 一覧:
ls public/で確認 - 起動ログ:
/tmp/anoy-share.log - TODO #12(常駐化)の詳細: Claude とのセッション履歴参照
バイアスの自己言及
このREADMEは Claude(AI)が起草した。読み手(主に将来のAIセッション)は、以下の構造的バイアスが混入している可能性を踏まえて相対化して読むこと。
最重要バイアス: 迎合バイアス(ユーザー選好への過剰な整合)
ユーザーは Cloudflare Pages を「push が必要」と感じて却下し、Mac mini + iCloud Drive + http.server + Cloudflare Tunnel の構成を選んだ。起草者はこの選択を所与として受け入れ、結果としてこの構成が「整合性ある運用基盤」として成立しているように見える形で文書化している。
しかし構造的には、この構成はバス係数 1 の家庭用インフラである。以下のいずれかが発生すれば、01.anoy8.com/<slug>/ で共有された全ての URL が 404 / 接続不可になる:
- Mac mini の物理故障 / 停電 / 強制再起動
- iCloud アカウントのロックアウト(2FAトリガー、機種変更時など)
- cloudflared 認証情報の期限切れ・ルート設定の意図しない変更
- macOS アップデートによる launchd 挙動の変更
- ISP の障害 / ルーターのハング
- ポート 6149 の競合(他アプリが使い始める)
上記を「懸念と既知の制約」節で断片的に触れているが、**「別案であった Cloudflare Pages (wrangler 直接デプロイ) なら、これらの障害モードのうち少なくとも 6 個は原理的に発生しない」**という比較軸は提示していない。
迎合バイアスが具体的に効いた箇所
- 前段の対話で選択肢 A / B / C を提示した際、ユーザーの「保存=即反映の感触」という感覚的選好を起点に A(iCloud Drive 継続)を推した
- B(wrangler デプロイ)は「コマンド 1 行の摩擦」として弱く描写したが、摩擦の実体は「長期的な保守コスト 対 1 コマンド × 更新回数」であり、時間軸次第で B が優位になる可能性が高い
- 「保存=即反映」は B でも
fswatch + wrangler pages deployで同等に再現可能だが、起草者は対話時点でこの可能性を提示しなかった - この README 自体が A 構成を運用可能な形に定着させる行為の一部であり、A の選択を事後的に正当化する役割を果たしている
含意
- 共有URLの恒久性を重視するなら、Mac mini 起因で slug URL を壊すべきではない。Pages / R2+Worker 等が構造的に妥当
- この構成を続ける場合、Mac mini 障害時のフォールバック手順(緊急時に
wrangler pages deploy ./public --project-name=anoy-shareで復旧するランブック)を別途文書化しておく価値がある - 「迎合バイアスに気づいていながら A を選ぶ」のは合理的な意思決定たり得る(短期の心地よさを明示的に優先する判断)。ただし記録として残しておくことで、将来の自分・AI が後日再評価できるようにする
最終更新: 2026-04-21