【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
whitenoiseGunicorn:本番で 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.43-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 yourapp6. 初回デプロイ → 初期セット(順番を守る)
git add .
git commit -m "Initial Heroku deploy"
git push heroku maincollectstatic / 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 接続 と 静的ファイル配信 まで確認
次回は、公開直後から役立つ 運用の初期整備(ログ/ロールバック/カスタムドメイン/小技)へ
では
次回に!
次回の記事
過去の記事
