[Django] Heroku デプロイ方法 2018年版

## この記事について

HerokuへのDjangoアプリケーションのデプロイ方法についての初心者向けのまとめです。内容はチュートリアルと同様、Freeレベルに最小構成のアプリをデプロイするまでとなります。

2017年12月にHerokuが「Heroku toolbelt」の後継となる「[django-heroku](https://github.com/heroku/django-heroku)」というデプロイ用パッケージをリリースしたので、デプロイ用の設定変更が少し簡単になりました。

参考：[Heroku Django デプロイ解説](https://devcenter.heroku.com/articles/deploying-python)

## Herokuの推奨構成

まずはアプリケーションの構成概要です。

Herokuでは平均的なDjangoアプリケーションための推奨構成を用意しています。とくに理由がなければ従いましょう。推奨構成ではアプリケーションサーバにGunicorn、静的ファイルの配信にWhitenoiseを使います。


参考：[Heroku Dev Center - Python Support](https://devcenter.heroku.com/categories/python-support)

### 推奨構成図

<img src="https://qiita-image-store.s3.amazonaws.com/0/217094/454d7cfc-4730-d86f-e209-7864ad9cde67.png" >

### 推奨パッケージの説明

- Gunicorn
 - rubyのunicornを元に開発されたpythonのアプリケーションサーバ。日本語の資料は少ないので、特徴については本家のunicornの資料を見るといいかも。
 - 公式： http://gunicorn.org/
 - 参考：[NginxとUnicornのぐぐりまとめ](https://qiita.com/PallCreaker/items/46eb7171f1eb2c3d77cf)
- Whitenoise
 - Djangoでは本来静的ファイルの配信に対応していないが、それを可能にするパッケージ。圧縮＆キャッシュにより普通のWebサーバより高速に応答する。
 - 公式： https://github.com/evansd/whitenoise/
- dj-database-url
 - データベースの接続情報を環境変数から指定できるようにする（変数名は「DATABASE_URL」）。無料のHerokuデータベースを特に設定せずに使えるのはこの仕組みを利用しているから。
 - 公式：https://github.com/kennethreitz/dj-database-url

## デプロイ手順

はじめての方は、まずDjango Girlsの説明を一読しましょう。日本語の資料としてはHerokuのデプロイについて一番わかりやすく書いています。

参考：[Django Girls Tutorial - デプロイ！](https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/deploy/)

以下の手順はjango Girls内容を整理したものです。順番に進めれば無事デプロイできるはずです。

### １．準備

開発ＰＣで以下の事項を完了させる。

- プロジェクトの作成
- [Herokuアカウントの作成](https://jp.heroku.com/free)
- [Heroku toolbelt（Git + ssh含む）のインストール](https://devcenter.heroku.com/articles/heroku-cli)

### ２．プロジェクトの修正

既存のプロジェクトに対してHerokuで必要なファイルの追加、設定ファイルの修正を行います。

#### ２－１．実行環境ファイルの追加

実行環境の設定をHerokuに伝えるファイルをプロジェクトディレクトリ直下に作成します。

|ファイル名|役割|
|:--|:--|
|runtime.txt|Pythonのバージョン指定|
|Procfile|Herokuプロセスの起動コマンド
|requirements.txt|依存パッケージのリスト|

[ファイル記述例]

```text:runtime.txt
python-3.6.6
```

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

`requirements.txt`は「pip freeze」コマンドで作成します。実行前に「gunicorn」および「django-heroku」をインストールしてください。

```shell:commandline
pip install gunicorn django-heroku
pip freeze > requirements.txt
```

※ django-herokuをインストールすると「whitenoise, pytz, django, dj-database-url, psycopg2」も同時にインストールされます。

※ Herokuはpipenvにも対応済みなので requirements.txt ではなく 「Pipfile、Pipfile.lock」でもＯＫです。

#### ２－２．設定ファイルの変更

Djangoの設定ファイル「mysite/settings.py」をHeroku用に変更します。ただし、普通に変更すると開発環境で動作しなくなるので、開発環境だけで専用の設定が有効になるような仕組みを作ります。

[修正対象ファイル]

|ファイル名|役割|
|:--|:--|
|mysite/local_settings.py|【新規作成】開発環境用設定ファイル
|mysite/settings.py|本番環境用設定ファイル
|.gitignore|Git管理除外リスト

[ファイルの記述例]

まず `mysite/local_settings.py` を作成し開発環境独自の設定を定義します。以下はデータベース定義とデバッグフラグの設定です。

```python:mysite/local_settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

DEBUG = True
```

次に既存の設定ファイルの最後に開発環境用ファイルの読み込みと`django-heroku`の実行を追加します。

```python:mysite/settings.py
DEBUG = False

try:
    from .local_settings import *
except ImportError:
    pass

if not DEBUG:
    import django_heroku
    django_heroku.settings(locals())
```

[django-heroku](https://github.com/heroku/django-heroku) では、Whitenoise、dj-database-urlなどのHeroku用の設定を一括で行われます。Django Girlsで行っている`mysite/wsgi.py`と`mysite/settings.py`への修正はすべてこのコードに含まれます。

実際にどのような設定を行われるかは[ソースコード](https://github.com/heroku/django-heroku/blob/master/django_heroku/core.py)を確認してください。

最後に`.gitignore`に`local_settings.py`を追加します。Heroku環境に`local_settings.py`はコピーされないので、開発環境の設定が有効になることはありません。

```text:.gitignore
<your_venv>
__pycache__
staticfiles
local_settings.py
db.sqlite3
*.py[co]
```

元の`settings.py`のコードが複雑になってしまいましたが、別の設定ファイル分離方法を使えば若干最初の手間は増えますが設定がよりシンプルに整理できます。

参考：[[Django] プロジェクト構成のベストプラクティスを探る - ２．設定ファイルを本番用と開発用に分割する](https://qiita.com/okoppe8/items/e60d35f55188c0ab9ecc)


### ３．Git ローカルリポジトリの準備

ローカルリポジトリが未作成の場合はコマンドラインで以下のgitコマンドを順に実行します。

```shell:
git init                                
git config user.name "Your Name"        
git config user.email you@example.com   
git add -A .                            
git commit -m "first commit"     
```

既存のリポジトリを使っている場合は普通にコミットしてください。

### ４．Heroku へのデプロイ

Heroku CLIのコマンドでHerokuにデプロイします。

```shell:
heroku login
heroku create <your-app-name>
git push heroku master
heroku ps:scale web=1
heroku run python manage.py migrate
heroku run python manage.py createsuperuser
```

以上でデプロイ作業は完了です。`heroku open` もしくは ブラウザでアプリケーションのURLにアクセスして動作を確認しましょう。

データベースはデフォルトのhobby-devレベルのものなので、必要ならアドオン設定から変更してください。

既存のアプリの修正を行う場合のgit remoteの設定については、こちらの記事が詳しいです。

- [Heroku にある Git リポジトリを楽に remote に設定する](https://qiita.com/ka_/items/2ad2826329abeb49dfa2#%E3%81%84%E3%81%A1%E3%81%84%E3%81%A1%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%AE-uri-%E3%82%92%E6%89%93%E3%81%A1%E8%BE%BC%E3%82%80%E3%81%AE%E3%81%AF%E9%9D%A2%E5%80%92%E3%81%A0)