VRChat 写真を Dropbox から R2 経由でサイトに載せる
VRChat ハブページ のスクリーンセーバーとフォトギャラリーに、Dropbox に入れたスクショを自動で反映する仕組みを作りました。
VRChat のスクショは 2160×3840 などデカいので、そのまま git に入れるとリポジトリが太ります。ブラウザから Dropbox を直接読むのも帯域と CORS の点で微妙だったので、VPS で日次バッチ → Cloudflare R2 → マニフェスト JSON だけ push という形にしました。
ざっくり構成
1 | Dropbox (VRChatPictures/guetan.dev/<見出し>/) |
手動で選んだアバター別写真(milfy/ など)は今まで通り git。Dropbox の「見出しフォルダ」アルバムだけ R2 に逃がしています。
Dropbox 側の整理
1 | VRChatPictures/guetan.dev/ |
フォルダ名がそのままギャラリーの見出しになります。撮ったらここに放り込むだけ。
なぜ R2 か
- git に画像を積まない(
vrchat-photos.jsonだけ更新) - Cloudflare Pages と同じダッシュボードで完結
- egress 無料(スクリーンセーバーで何度読み込まれても転送料ゼロ)
- 無料枠 10 GB/月で、最適化後の写真なら当面 $0
VPS でやっていること
専用ユーザ vrchat-sync を作り、毎日 4:00 に tools/sync-vrchat-dropbox.sh を実行しています。
git pullで記事や手動キュレーション写真を取得rclone copyで Dropbox →~/vrchat-albums/tools/vrchat-photos.pyで長辺 1920 に最適化しマニフェスト生成rclone copyで R2 のalbums/へvrchat-photos.jsonだけ commit & push → Cloudflare Pages がデプロイ
rclone の Dropbox 認証は VPS だとブラウザが使えないので、SSH の -L 53682:127.0.0.1:53682 でポートフォワードして手元のブラウザから許可しました。
R2 はバケット限定の API トークンだと ListBuckets が 403 になるので、rclone 側で no_check_bucket = true が必要でした。
サイト側
フロントはもともと /vrchat-photos.json を読んでスクリーンセーバーを回しているだけなので、マニフェストの src が R2 の絶対 URL になればそのまま動きます。
1 | { |
運用のコツ
- VPS では
VRCHAT_SKIP_REPO_OPTIMIZE=1にして、git 管理の宣材・アバター画像は触らない(Dropbox アルバムだけ最適化) - 写真に変更がなければ
vrchat-photos.jsonは書き換えず、空の commit もしない - R2 API トークンをローテーションするときは、新トークンで rclone を更新してから古いトークンを削除(手順は README の「API トークンのローテーション」)
詳細手順
リポジトリ内の deploy/vrchat-sync/README.md に、VPS セットアップから rclone・cron まで書いてあります。
今後
- 古い git 内 VRChat 写真も R2 に移してリポジトリをさらに軽くする(履歴の整理は別作業)
VRChat ハブページ で動作を確認できます。



























































