🌊 S3 死闘の振り返り

  1. S3 導入を決意 • 当初は EC2 内部の /static/ に collectstatic して配信していたが、 「スケールアウトや再デプロイに弱い」という課題が見えてきた。 • そこで AWS S3 で静的ファイルとメディアファイルを管理する方針に。
  2. 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 に飛ぶように準備。

⸻

  1. IAM 権限との戦い • 最初は EC2 から S3 に書き込めず「アクセス拒否」地獄。 • 解決策: • EC2 にアタッチした IAM ロールに AmazonS3FullAccess を付与。 • 必要に応じて最小権限ポリシーを作成し、s3:PutObject / s3:GetObject / s3:ListBucket を許可。

⸻

  1. collectstatic と STATIC_ROOT の罠 • STATICFILES_DIRS と STATIC_ROOT の設定がごちゃつく。 • 開発環境 → STATICFILES_DIRS = [BASE_DIR / "static"] • 本番環境 → STATIC_ROOT = None にして S3 側だけ使う。 • 途中で "NoneType' object has no attribute 'startswith'" エラーが出て詰まったことも。

⸻

  1. ローカルと本番の切り分け • 「ローカル開発では runserver で /static/ を直接読む」 • 「本番は S3 から配信する」 という2段構えに落ち着く。 これで DEBUG=True ではファイルが見え、DEBUG=False では S3 に依存する形になった。

⸻

  1. 動作確認の死闘 • aws s3 ls でバケットを直接叩いて確認。 • ようやく以下の結果が出て勝利を確信:

$ aws s3 ls s3://s3stylelog/static/ PRE admin/ PRE css/ PRE img/ PRE js/

•	つまり collectstatic の成果物が s3stylelog バケットに揃っている!

⸻

✅ 成果 • EC2 から S3 へのアップロード成功 • Django 側も S3 と連携できるようになった • これで 静的ファイル配信の安定化 & スケーラブル運用が可能に!