📸

プライベート写真の保存にGoogle Driveの課金が高いので自作した

に公開

初めに

子供の写真を撮っているとスマホの画像があっという間に増えてしまいます。Androidユーザーの私はGoogleフォトにバックアップされるわけですが、無料の枠では収まらなくなってしまいました。
少しでも月額を減らすために自作してみたらいい感じに費用を削れたので紹介したいと思います。


一覧


アップロード

コスト感

1$ / 150円換算

50GB 100GB 200GB
Google Drive 290円 290円 440円
作ったもの 36円($0.24) 81円($0.54) 171円($1.14)

基本的にはストレージのみです。

使用技術

クライアント

Next.js 16をVercelで動かしています。個人アプリなので無料で利用できます。
OpenNext(Cloudflare)で動かしていましたが一部動かない部分があったのでやめました。
VercelのHobbyプランでは、next/imageの最適化上限が5,000回/月のため今回のケースでは不十分です。そのため、画像のリサイズなどはAPI Routesでエンドポイントを作っています。

認証はAuth.jsでGoogle認証のみ実装しています。DBは無しで、メールアドレスの許可リストのみ利用できます。

画像配信

Cloudflare WorkersからBackblaze B2のバケットを読み取って配信しています。基本的には下記のまま実装しています。
https://www.backblaze.com/docs/cloud-storage-deliver-private-backblaze-b2-content-through-cloudflare-cdn
Auth.jsの認証Guardを作るのにTypeScriptを使いたかったのでついでにHonoで書き直しています。

許可されたユーザー以外はURLの直叩きでも表示できません。

オブジェクトストレージ

Backblaze B2を使っています。ここが肝なので料金が抑えられそうなものを厳選しました。
バケットはprivateで、基本的にアプリからしか見ることはできません。

ストレージ料金も激安ですが、cloudflareから配信することで読み取り無料なのは大きいです。

その他

  • turborepo
  • biome

機能

用途は子供の画像を夫婦間で共有の場所にアップしておき、閲覧できるようなイメージです。

  • 画像アップロード(万単位のアップロード想定)
  • 一覧表示
    • 無限スクロール
    • 表示列数の変更
  • 詳細表示
    • 動画再生対応
    • スライド表示
    • ダウンロード
  • 閲覧制限
    • 許可リストのアドレスのみ許可
    • URL直叩きも禁止

まとめ

利用料を見ても想定したコスト感になっていて満足しています。
子供の写真は夫婦間で送り合い、2つのスマホに同じ画像が存在する状況が多いと思いますが同じ場所のものを共有できるようになってよかったです。また、送られたものを厳選して保存する手間がなくなったのも便利でした。

こういったものは一度課金したら一生払い続けることになりそうなので、節約できてよかったです。

続編

画像配信の仕組みをCloud Run(Rust)+ Cloudflare Workersでリニューアルしました。
https://zenn.dev/chot/articles/original-media-storage-rebuild

Discussion