🌊 S3 死闘の振り返り
- S3 導入を決意
• 当初は EC2 内部の /static/ に collectstatic して配信していたが、
「スケールアウトや再デプロイに弱い」という課題が見えてきた。
• そこで AWS S3 で静的ファイルとメディアファイルを管理する方針に。
- Django 側での準備
• django-storages + boto3 を導入。
• settings.py に以下のように設定を追加:
INSTALLED_APPS += ["storages"]
AWS_STORAGE_BUCKET_NAME = "s3stylelog"
AWS_S3_REGION_NAME = "ap-northeast-1"
AWS_DEFAULT_ACL = None
STATICFILES_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
• これで collectstatic が S3 に飛ぶように準備。
⸻
- IAM 権限との戦い
• 最初は EC2 から S3 に書き込めず「アクセス拒否」地獄。
• 解決策:
• EC2 にアタッチした IAM ロールに AmazonS3FullAccess を付与。
• 必要に応じて最小権限ポリシーを作成し、s3:PutObject / s3:GetObject / s3:ListBucket を許可。
⸻
- collectstatic と STATIC_ROOT の罠
• STATICFILES_DIRS と STATIC_ROOT の設定がごちゃつく。
• 開発環境 → STATICFILES_DIRS = [BASE_DIR / "static"]
• 本番環境 → STATIC_ROOT = None にして S3 側だけ使う。
• 途中で "NoneType' object has no attribute 'startswith'" エラーが出て詰まったことも。
⸻
- ローカルと本番の切り分け
• 「ローカル開発では runserver で /static/ を直接読む」
• 「本番は S3 から配信する」
という2段構えに落ち着く。
これで DEBUG=True ではファイルが見え、DEBUG=False では S3 に依存する形になった。
⸻
- 動作確認の死闘
• aws s3 ls でバケットを直接叩いて確認。
• ようやく以下の結果が出て勝利を確信:
$ aws s3 ls s3://s3stylelog/static/
PRE admin/
PRE css/
PRE img/
PRE js/
• つまり collectstatic の成果物が s3stylelog バケットに揃っている!
⸻
✅ 成果
• EC2 から S3 へのアップロード成功
• Django 側も S3 と連携できるようになった
• これで 静的ファイル配信の安定化 & スケーラブル運用が可能に!