HerokuにDjangoアプリをデプロイする方法


はじめに

Djangoで作っていたアプリを、Herokuで動かしたいと思ったときに躓いたのでそのメモ。

前提

  • gitはインストール済
  • Herokuアカウント作成済
  • HerokuCLIインストール済
  • デプロイしたいDjangoアプリは完成している

パッケージのインストール

django-toolbelt

pip install django-toolbelt

詳細は→こちら

これをインストールすることで下記パッケージがインストールされる。

  • Django
    • Django本体
  • psycopg2
    • PythonでpostgreSQLを扱いやすくする
  • gunicorn
    • HerokuでDjangoをデプロイするときに推奨されている、Webサーバー
  • dj-database-url
  • dj-static

whitenoise

pip install whitenoise

WSGIアプリケーションのための静的ファイルを配信するのを簡単にしてくれるライブラリ。

Djangoプロジェクトの修正

Herokuにデプロイするためには下記ファイルを追加・修正をしなければならない。

  • requirements.txt
    • アプリを動かすために必要なパッケージを一覧としてまとめておくファイル
  • Procfile
    • Herokuプロセスの起動コマンド
  • runtime.txt
    • 使用するPythonのバージョンを指定
  • .gitignore
    • sqliteとかが一緒に入らないようにする
  • wsgi.py
    • setting.pyから環境変数を受け取ってDjangoを動かしている...らしい

requirements.txtの作成について

下記でファイルを作成できる

pip freeze > requirements.txt

ファイルの中身は下記のような感じになっている。

dj-database-url==0.5.0
Django==2.2.3
django-toolbelt==0.0.1
gunicorn==19.9.0

Procfile(例)

web: gunicorn <your-project-name>.wsgi --log-file -

runtime.txt(例)

python-3.6.1

.gitignore

*.pyc
venv
staticfiles
db.sqlite3

wsgi.py

wsgi.py
import os

from dj_static import Cling
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_project_name.settings")

application = Cling(get_wsgi_application())

作成したファイルは下記の位置に配置する。

├─django_project_name
   │  db.sqlite3
   │  manage.py
   │  Procfile ☆
   │  requirements.txt ☆
   │  runtime.txt ☆
   │  .gitignore ☆
   │  
   ├─django_app_name
   │    admin.py
   │    apps.py
   │    forms.py
   │    models.py
   │    tests.py
   │    urls.py
   │    views.py
   │    __init__.py
   │          
   └─django_project_name
         settings.py
         urls.py
         wsgi.py ☆
         __init__.py

Django設定ファイルの修正

次に、設定ファイル「settings.py」を修正する。

DB周りの設定

HerokuではDBはpostgresを使用する(SQLiteは使えない?)。そのため、動作環境によって使用するDBの設定を変えなければならない。
また、DEBUG=Falseにもしておく。

書き方は下記の方を参考にさせていただきました。
- Django2.0でHerokuデプロイ手順

settings.py
# hostnameが自分のpcの場合は、sqliteに接続する
# そうでない場合はherokuのpostgresに接続する
from socket import gethostname
hostname = gethostname()
if "myhostname" in hostname:
    DATABASES = {
       'default': {
           'ENGINE': 'django.db.backends.sqlite3',
           'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
       }
    }
    ALLOWED_HOSTS = []
else:
    # 本番環境ではデバッグモードはfalseにしておく
    DEBUG = False
    import dj_database_url
    db_from_env = dj_database_url.config()
    DATABASES = {
        'default': dj_database_url.config()
    }
    ALLOWED_HOSTS = ['*']

静的ファイルの設定について

DEBUGをfalseにすると、CSSなどの静的ファイルが適用されていない。
HerokuやWebサーバーにデプロイするときは静的ファイルの置き場所を一か所にまとめる必要がある。
まず、settings.pyにどこに集めるかなどの設定を記述する。

settings.py
import os

# settingsファイルのパスが入る
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# manage.pyのcollectstaticをした時に、静的ファイルがどこに格納されるか指定する
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

# HerokuやWebサーバーに静的ファイルを見に行く場所を指定する
STATIC_URL = '/static/'

# 各アプリケーションのstatic以外に配信するディレクトリがある場合に追加
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, '..', 'django_app_name', 'static'),
)

また、インストールしたwhitenoiseの設定を行う
MIDDLEWAREについては'django.middleware.security.SecurityMiddleware'の後ろに追加する。

settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware', 追加部分
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...
]

STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'

上記の追記後、下記コマンドを実行する

python manage.py collectstatic

すると、指定した場所にstaticフォルダが作成され、静的ファイルが集められている。

├─django_project_name
   │  db.sqlite3
   │  manage.py
   │  Procfile
   │  requirements.txt
   │  runtime.txt
   │  
   ├─django_app_name
   │    admin.py
   │    apps.py
   │    forms.py
   │    models.py
   │    tests.py
   │    urls.py
   │    views.py
   │    __init__.py
   │          
   └─django_project_name
         static ☆
         settings.py
         urls.py
         wsgi.py
         __init__.py

Herokuにデプロイ

下記は準備できているものとし、ここでは取り上げません。

  1. Herokuアカウント
  2. Git こちらを参考に
  3. Heroku Command Line Interface こちらから

まずはコミットしておく

$ cd django_project_name
$ git init
$ git add .
$ git commit -m "はじめてのコミット"

HerokuCLIをインストールすると、Herokuコマンドが使えるようになる。
Herokuアカウントを作った際の情報で下記コマンドでログインする。

$ heroku login

次に、デプロイしたいアプリケーションの改装に移動し、下記コマンドを打つ

$ heroku create
> Heroku上にアプリを作成する。

$ git push heroku master
> Heroku上にソースコードを渡す。

$ heroku run python manage.py migrate
> ここでもmigrateをしてあげる

$ heroku ps:scale web=1

$ heroku open

完了!!

以上で、デプロイされているはず。