見出し画像

【IT】HerokuでDjangoを“最短で正しく”公開する(第1回:Heroku 上に Django を公開)

皆さま、こんにちは

今回から2回に分けてDjangoアプリケーションをHerokuへ公開する手順を記載します。

(Heroku未経験の方向け。ゼロから公開までを、何故その設定が必要かまで含めて解説します)



0. はじめに:この回でやること/やらないこと

やること

  • ローカルの Django を Heroku にデプロイして公開

  • 本番向けの最小設定:`DEBUG/ALLOWED_HOSTS`、CSRF は ALLOWED_HOSTS から https で自動生成

  • Heroku Postgres に接続(`dj-database-url` 利用)

  • 静的ファイル配信(Whitenoise)+ `collectstatic`

  • 初回 `migrate / createsuperuser` まで

やらないこと

  • 料金や各社の詳細価格比較(価格は変動するため、ここでは手順と設計に集中)

  • 大規模運用のチューニングや厳格なセキュリティ強化(必要になったら別記事で拡張)


1. まず押さえる:Herokuとは/無料枠は?/なぜHeroku?

1-1. Herokuってそもそも何?

Heroku は PaaS(Platform as a Service)。アプリは Dyno(Heroku管理のLinuxコンテナ) 上で稼働します。
`git push` をトリガーに ビルド → リリース → 実行 まで自動で進み、OSやWebサーバの細かい設定に時間を割かずに済みます。DB 等の周辺機能は Add-on(今回は Heroku Postgres)で拡張します。

1-2. Herokuって無料ではなかったの?

無料Dyno/無料Postgres/無料Redis は廃止済みで、現在は有料前提です。金額は変動しうるため、本稿では具体額に踏み込まず、安全に動かす手順に集中します。

1-3. 何故 Heroku?(Vercel/Render/AWS との比較の観点)

  • Heroku:`git push` → 常駐Web(Gunicorn 等)+ Heroku Postgres の接続までが最短。学習→運用への移行が簡単。

  • Vercel:フロント&サーバレス中心。24/7 常駐の Django や長時間処理は設計工夫が必要。

  • Render:常駐Web+マネージドPostgresを同一基盤で提供。検証に向く(本番は有料推奨)。

  • AWS(Elastic Beanstalk 等):自由度は最大だが部品選定・運用設計が自前。本稿の「最短で正しく公開」という目的には過剰。

今回の目的は「Django を常駐プロセスとして素直(シンプル)に公開し、Postgres と組み合わせる」こと。私にとってのベストプラクティスとして最短ルートが Heroku でした。


2. 事前準備(ローカル環境)

  • Heroku CLI:`heroku --version`(未インストールなら公式手順で導入)

  • Git:`git --version`

  • Python 3.13+ と pip:`python --version`/`pip --version`

  • Django プロジェクト:`wsgi.py` がある通常構成を想定(例:`config/wsgi.py`)

迷いポイント:.gitignore
・ `staticfiles/` は コミットしない(`collectstatic` で生成)
・`__pycache__/`、仮想環境、機密ファイル類を除外

プロジェクト構成例

yourproject/
├─ manage.py
├─ config/
│  ├─ settings.py
│  ├─ wsgi.py
│  └─ urls.py
└─ app1/ app2/ ...

3. 必要ファイル(“最短で正しく”動かす最小セット)

3-1. `requirements.txt`(例)

Django>=5.0
gunicorn
psycopg2-binary
dj-database-url
whitenoise
  • Gunicorn:本番で WSGI アプリを起動

  • psycopg2-binary:Postgres 接続(ビルドが軽い)

  • dj-database-url:`DATABASE_URL` を Django 設定へ取り込む

  • Whitenoise:追加インフラなしで静的配信

3-2. `Procfile`(ルート直下)

web: gunicorn config.wsgi:application
# ↑ "config" はあなたの構成に合わせる(例: myproject.wsgi)
  • web 行が Heroku で起動される本番プロセス

3-3. `runtime.txt`(任意:Python を固定したい場合)

python-3.13.4

3-4. `settings.py` の最小差分

CSRF は `ALLOWED_HOSTS` から https で自動生成/`SECURE_PROXY_SSL_HEADER` は使わない

# settings.py(抜粋)
import os
from pathlib import Path
import dj_database_url

BASE_DIR = Path(__file__).resolve().parent.parent

# --- 本番切替(Herokuでは環境変数で制御) ---
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'

# 例: "yourapp.herokuapp.com,example.com"
ALLOWED_HOSTS = [h for h in os.getenv('ALLOWED_HOSTS', '').split(',') if h]

# CSRF は ALLOWED_HOSTS から https で自動生成(別変数は不要)
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS]

# --- DB(Heroku の DATABASE_URL を取り込む)---
DATABASES = {"default": dj_database_url.config(conn_max_age=600, ssl_require=True)}

# --- 静的ファイル(Whitenoise)---
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
MIDDLEWARE = [
    "whitenoise.middleware.WhiteNoiseMiddleware",  # なるべく先頭側(SecurityMiddlewareの直後あたり)
    # ...既存のミドルウェア...
]
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"

ポイント

  • `SECRET_KEY` は Heroku の Config Vars に設定(ソース直書き禁止)

  • 二重引用符は不要:`DEBUG=false` を `"false"` と入れると文字列扱いになる

  • Whitenoise は 上位(SecurityMiddleware の直後あたり)に置くと安定


4. Heroku アプリ作成 → Postgres 付与

heroku login

cd /path/to/your-django-project
git init  # 既存なら不要

# アプリ作成(app名=そのままドメイン: yourapp.herokuapp.com)
heroku create yourapp

# 既存アプリに紐付ける場合だけ
heroku git:remote -a yourapp

# Postgres 付与(DATABASE_URL が自動設定)
heroku addons:create heroku-postgresql:essential -a yourapp

確認:`heroku config -a yourapp` に `DATABASE_URL` が見えればOK。


5. Config Vars(環境変数)を設定

Heroku Dashboard → Settings → Reveal Config Vars(CLIでも可)

CSRF は `ALLOWED_HOSTS` から https 付きで自動生成
ダブルクォートは入れないでください(`"false"` は文字列になります)。

CLI 例:

heroku config:set \
  SECRET_KEY='your-production-secret' \
  DEBUG=false \
  ALLOWED_HOSTS='yourapp.herokuapp.com,example.com' \
  -a yourapp

6. 初回デプロイ → 初期セット(順番を守る)

git add .
git commit -m "Initial Heroku deploy"
git push heroku main

collectstatic / migrate / createsuperuser

HerokuのフラグとDjangoのフラグは `--` で区切る

# 静的ファイル収集
heroku run --app yourapp -- python manage.py collectstatic --noinput

# マイグレーション
heroku run --app yourapp -- python manage.py migrate

# 管理ユーザー作成
heroku run --app yourapp -- python manage.py createsuperuser

補足: --no-tty は任意です(基本なしでOK)。対話不要の時に出力をスッキリさせたい場合だけ付けてください。

例)heroku run --no-tty -a yourapp -- python manage.py migrate

豆知識:自動 collectstatic

  • デフォルトで ビルド時に自動実行されます。最初は手動で成功パターンを確認 → 安定したら自動任せでもOK。

  • 一時的に止めたい場合のみ `DISABLE_COLLECTSTATIC=1`(恒常運用は非推奨)。


7. 動作確認(チェックリスト)

  • トップページが 200 で表示

  • `/admin/` にログインできる

  • CSS/JS/画像が 200(静的OK)

  • `DEBUG=false` で Django のデバッグページが出ない

  • `DisallowedHost` → `ALLOWED_HOSTS` を見直し

  • `CSRF 403` → 使用ドメインを漏れなく(`www` あり/なしを両方使うなら両方入れる)


8. つまずきやすい所と解決の型

  • `Nonexistent flag`
    → `heroku run --app <app> -- python manage.py <cmd> --<flags>` に統一(`--` が大事)

  • `ModuleNotFoundError: gunicorn`
    → `requirements.txt` に `gunicorn` を追加して再デプロイ

  • 静的 404/collectstatic 失敗
    → Whitenoise 設定、`STATIC_ROOT`、`.gitignore`(`/staticfiles` をコミットしていないか)

  • DB 接続エラー
    → Postgres アドオン付与、`DATABASE_URL` の存在、`dj-database-url` の導入確認

  • 管理画面だけ 403(CSRF)
    ALLOWED_HOSTS の不足が大半(本記事ではそこから CSRF を自動生成)

(追加の運用系)

  • H10/H14(アプリクラッシュ/無応答)→ `heroku logs --tail` でエラー行を確認

  • R14(メモリ超過)→ 高負荷処理の分離や一時的スケールで対処

  • Slug が大きすぎる→ `.slugignore` で不要ファイルを除外


9. まとめ(第1回)

  • 必要最小限の設定で Heroku 上に Django を公開

  • Postgres 接続静的ファイル配信 まで確認

  • 次回は、公開直後から役立つ 運用の初期整備(ログ/ロールバック/カスタムドメイン/小技)へ


では
次回に!


次回の記事

過去の記事



いいなと思ったら応援しよう!