🚀 実戦の大ボス:クラウドプラットフォームの容量制限とセキュリティ防御
これまでのチュートリアルに従ってプロジェクトを作成し、クラウドにアップロードしようとしたとき、「プロジェクトが大きすぎて Git がクラッシュする」や「アップロード失敗」という悲惨な状況に突然遭遇することがよくあります。
これはあなたのコードにバグがあるのではなく、主要クラウドプラットフォームの**「ハードウェア容量の天井」**に触れてしまったからです! この章では、デプロイと配布時に最も遭遇しやすい3つの地雷と、プロのエンジニアとしてそれらを完璧に回避する方法を解説します!
💣 地雷1:GitHub の 100MB ファイル制限
発生シナリオ
自分の作品やソースコードを ZIP ファイルにパッケージ化し、プロジェクト内でクライアントにダウンロード提供しようとするとき。ターミナルで zip -r my_project.zip . と入力すると、このファイルが数百MB 甚至 1GB以上にもなることがわかります!
git push を実行すると、ターミナルは冷酷にエラーを報告します:
remote: error: GH001: Large files detected. You may want to try Git Large File Storage...remote: error: File my_project.zip is 737.00 MB; this exceeds GitHub's file size limit of 100.00 MB
なぜこうなるのか?
開発過程の「ゴミ」と「履歴」をすべて含めてしまっているからです:
node_modules:数万のパッケージファイルが含まれ、簡単に500MBを超えます。.git:この隠しフォルダはすべての commit を記録しており、歴史が長いほどファイルサイズが大きくなります!.nextやdist:これらはコンパイルされた一時ファイルです。
✅ 解決策:プロフェッショナルな除外スク��プトを作成
手動でパッケージ化するのはやめましょう!プロジェクトルートに package_source_code.sh スクリプトを作成し、zip の -x パラメータを使用して不要なファイルを正確にフィルタリングし、機密の .env キーを削除して .env.example に置き換えます。
# package_source_code.sh 例
OUTPUT_DIR="public/source_codes"
name="my_project"
# 古い圧縮ファイルを削除し、zip コマンドが増分更新だけを行わないようにする!(これが超重要)
rm -f "$OUTPUT_DIR/${name}_source.zip"
zip -r -q "$OUTPUT_DIR/${name}_source.zip" . \
-x "node_modules/*" \
-x ".git/*" \
-x ".env" \
-x ".env.local" \
-x ".next/*" \
-x "dist/*" \
-x "public/source_codes/*" \
-x ".vercel/*" \
-x "*/.vercel/*" \
-x "*.jpg" -x "*/*.jpg" \
-x "*.png" -x "*/*.png"
echo "✅ パッケージング完了!"
実行結果:700MBあったプロジェクトが、パッケージ化後 1MB未満 にスリム化!GitHub へのプッシュがスムーズに!
💣 地雷2:Supabase 無料版の 50MB ファイル制限
発生シナリオ
ZIP ファイルを GitHub や Vercel に置きたくない(Vercel のデプロイ容量割り当てを消費するため)と考え、Supabase Storage にアップロードしようとすると、途中でエラーが発生:
This project has a global file size limit of 50 MB.
なぜこうなるのか?
Supabase の Free Tier(無料版)は便利ですが、無料のファイルホスティングとして悪用されるのを防ぐため、単一ファイルのアップロードを50MB以下に厳しく制限しています。上記のスクリプトでプロジェクトを1MBにスリム化できれば問題ありません。
しかし、ファイルが「本当に50MBを超える」場合(例えば大量のチュートリアル動画や高解像度デザインファイルを含む場合)はどうすればよいでしょうか?
✅ 解決策:Google Drive を使った見えないリダイレクト
一銭もかかりません!
- 大きなファイルを自分の Google Drive にアップロードし、「リンクを知っている全員が閲覧可」のURLを取得します。
- フロントエンド画面には「ダウンロード」ボタンを配置します。
- キーポイント:ボタンを Google Drive に直接リンクさせず、バックエンド API(例:
/api/download)にリンクさせます。 - バックエンド API でユーザーがログイン済みかつ有料会員であることを確認し、
return NextResponse.redirect("あなたのGoogle Drive URL")を実行します。 これで50MB制限をゼロコストで回避でき、ある程度の権限保護も維持できます!
💣 地雷3:public フォルダの盗難リスク
発生シナリオ
スリム化した ZIP ファイルを Next.js の public/source_codes/ フォルダに配置し、フロントエンドで if (有料会員) { ダウンロードボタンを表示 } という条件分岐を書いたとします。
なぜ危険なのか?
Next.js において public フォルダは「全世界に公開」される静的リソースです!
ボタンが隠されていても、悪意のあるユーザーが実際のURL(例:https://your-domain.com/source_codes/my_project.zip)を推測または取得すれば、ログインや支払いなしで直接ダウンロードできてしまいます!
✅ 解決策:Supabase Private Bucket + 一時署名付きURL (Signed URL)
これが知識有料化プラットフォームに必要な防御仕様です:
- プライベートバケットの作成:Supabase Storage に
source-codesという名前の Bucket を作成し、Private(公開アクセス不可)に設定します。 - バックエンドによる一時キーの発行:
ユーザーがダウンロードをクリックすると、作成したバックエンドの
/api/downloadAPI を呼び出します。API が権限を確認した後、最高権限のService Role Keyを使用して Supabase に「60秒間だけ有効な一時ダウンロードURL」をリクエストします。
// src/app/api/download/route.ts コア防御ロジック
import { createClient as createSupabaseClient } from '@supabase/supabase-js';
// ... 前略:ユーザーが有料会員かどうかを確認 ...
// Service Role Key を使用して RLS 制限を回避
const supabaseAdmin = createSupabaseClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
// 60秒後に失効するダウンロードURLを生成
const { data, error } = await supabaseAdmin
.storage
.from('source-codes')
.createSignedUrl(fileName, 60, {
download: fileName // ブラウザに強制ダウンロードさせる
});
return NextResponse.redirect(data.signedUrl);
この究極の防御により、誰かがURLを共有しても60秒後には自動的に無効化され、紙切れ同然になります!これがソフトウェアエンジニアの収益化を守る最強の堀です!🏰