[Heroku]Django WEB App デプロイ（完）2019/6月版

#Django製アプリを「Heroku」へのデプロイ

![スクリーンショット 2019-06-27 19.17.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/1ae8d772-ab74-dda4-500a-67eeefc34a73.png)

コード:[https://github.com/MachinoTensei/kiite-kikasete](https://github.com/MachinoTensei/kiite-kikasete)

##はじめに
この記事を見てくださっている方はいくつものサイトを見ては、エラーを繰り返している方も多いと思います。
僕はデプロイに丸一日を要しました。他サイトを見ながら試行錯誤してやっとデプロイできましたが、なんせ、拡張子なしのファイル(後で出てきます)の作り方すら知らなかった僕にとっては、もう少し詳しく教えて欲しい！というところも多かったです。
もちろん、記事を書いてくださる方には感謝していますし、この記事よりも専門的な知識は多く得られます。
ですので、**この記事では細かな説明もしつこいくらいに入れていきながら解説**したいと思います。
そのため、長めの記事ですが、やっていることはそんなに多くありません。
読んでくださる方が、多くても数時間でデプロイできるようにしたいと思います。（一回もエラーが出ないなら、30分もかかりません。）

##前提条件（対象者）
- データベース(MySQL, phpMyAdmin)を用いたアプリを作成済み
- ローカルホストではきちんと動作するアプリが完成している
- [Heroku](https://jp.heroku.com/)のアカウントを持っている（無料）
- GitHub, git のコマンドを使える（僕のように調べながらでも使えればいいと思います）

###開発環境
```python
Mac OS
python            3.7.3
dj-database-url   0.5.0 #後でインストールします
Django            2.1    
django-bootstrap4 0.0.8  
gunicorn          19.9.0 #後でインストールします
pip               19.1.1 
psycopg2-binary   2.8.3 #後でインストールします
PyMySQL           0.9.3  
pytz              2019.1 #後でインストールします
setuptools        41.0.1 
sqlparse          0.3.0  
whitenoise        3.3.1 #後でインストールします
#「後でインストール」以外のものは、必要かはわかりません。
#ローカルで動いているのなら、この[pip list]はそんなに気にすることもないと思います。
```

###最終的なファイル構成
どこのファイルかわからない（説明不足）時は、この画像で判断してください。
紫色の線のファイルはこの後追加します。他のファイルはみなさんあると思います。（場合によって、staticファイルとかはないかも）
![スクリーンショット 2019-06-27 16.37.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/461b7931-66db-d9e5-81d3-de372e9a2e15.png)

##(１)必要なものをインストールする
![スクリーンショット 2019-06-27 19.40.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/3a108632-5e70-f64e-2234-01306f4a5d65.png)

下記のように、必要なものをインストールしてください。
**※注意（下の文を必ず読んでください）**
「whitenoise」はバージョン３を指定してください。指定しないと４がインストールされ、この記事の方法だとうまくいきません。
また、「psycopg2」のインストールができない場合は「pip install psycopg2-binary」をインストールしてください。
`pip install gunicorn django-heroku`で下記のものを一括インストールできるらしいが、僕はできませんでした。
試してみるのもありかもしれないです。

```:terminal
(dj)$ pip install dj-database-url
(dj)$ pip install gunicorn
(dj)$ pip install whitenoise==3.3.1 👈バージョンを指定しないと whitenoise4.x.x がインストールされる
(dj)$ pip install psycopg2　👈エラーが出る可能性あり
(dj)$ pip install pytz
```

##（２）ファイルを追加する
![スクリーンショット 2019-06-27 19.42.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/6da7c1d6-716a-d6c7-1953-c4b664fb3079.png)
![スクリーンショット 2019-06-27 19.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/60fa23bf-e855-8dd8-7983-af78cfda0c1a.png)



Herokuへデプロイするのに必要なファイルを作成していきます。
（.gitignore, Procfile, requirements.txt, runtime.txtを追加します。）

###（２-１）「.gitignore」を新規作成
```:terminal
#いつもの開発環境(venv)で実行してください。

(dj)$ cd myapp7  👈プロジェクトに移動(外側のディレクトリであることに注意)（myapp7のところは自分のに変える）
(dj)myapp7 $ touch .gitignore　👈これを実行すると「.gitignore」が作られる

Mac の場合は、Finderで「Shift + cmd + .」で見えるようになる
```
###（２-２）「.gitignore」を編集する
「.gitignore」を開いて、以下のように編集
（dj の部分は人によって異なる）

```:.gitignore
dj　👈これは自分の開発環境の名前(terminalの$マークの後ろの文字)
__pycache__
staticfiles
db.sqlite3
*.py[co]
```
###（２-３）「Procfile」を新規作成
```:terminal
#先ほどの続きで問題ないです。ディレクトリは外側のmyapp7

(dj)myapp7 $ touch Procfile　👈これを実行すると「Procfile」が作られる

Mac の場合は、Finderで「Shift + cmd + .」で見えるようになる
```
###（２-４）「Procfile」を編集する
Procfileはこの１行だけです。
スペースなどを省略するとエラーの原因になるため、コピペをお勧めします。
そのあとに、**myapp7の部分を自分のプロジェクト名に変更**してください。

```:Procfile
web: gunicorn myapp7.wsgi --log-file -
```

###（２-５）「requirements.txt」を新規作成
下のコマンドを実行するだけでOK

```:terminal
(dj)myapp7 $ pip freeze > requirements.txt
```
念の為、下のように記載されたファイルができているか確認してください。

```:requirements.txt
dj-database-url==0.5.0
Django==2.1
django-bootstrap4==0.0.8
gunicorn==19.9.0
psycopg2-binary==2.8.3
PyMySQL==0.9.3
pytz==2019.1
sqlparse==0.3.0
whitenoise==3.3.1
psycopg2==2.7.6.1　👈上で「psycopg2」がインストールできなかった人は追加
```

###（２-６）「runtime.txt」を新規作成
これは、CotEditorなり、普通のテキストエディタなりを開いて以下の１行を書きこんで保存してください。（このファイルは、Procfile同様に１行だけ）
保存場所は上の最初の画像を参照。
pythonのバージョンは自分が使用しているものに置き換えてください。
ただし、python2は想定していません。ご了承ください。

```
python-3.7.3
```

##（３）「local_settings.py」を新規作成
![スクリーンショット 2019-06-27 19.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/c8b0dc90-d926-df60-d62d-98566dbc644c.png)

settings.pyのデータベース接続部分をコピーして、新たに作成する「local_settings.py」に貼り付けします。（このファイルの保存場所は上の画像を確認してください。）

①settings.pyからDATABASEの部分をコピーする（DATABASEの部分は人によって異なると思います。）

②local_settings.pyという名前で新たに作成したファイルに、貼り付け（下のような感じになります。少しも省略していないため、local_settings.pyはこれが全てです。）

「👈」の部分以外は人によって異なると思います。（Django2, MySQL, phpMyAdminの組み合わせの人は、`"NAME": "kiitedb",`以外は下と全く同じになっても不思議ではありません。）

```python:local_settings.py
#この上には何もありません
import os　👈

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))　👈

import pymysql
pymysql.install_as_MySQLdb()

DATABASES = {
    'default': {
        #'ENGINE': 'django.db.backends.sqlite3',
        #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        "ENGINE": "django.db.backends.mysql",
        "NAME": "kiitedb",👈ここは人によって違う
        "USER": "root",👈場合によっては違う
        "PASSWORD": "root",👈場合によっては違う
        "HOST": "127.0.0.1",
        "PORT": "3306",
    }
}

DEBUG = True　👈
#この下には何もありません
```
###「.gitignore」に「local_settings.py」を追加
先ほど作成した、「.gitignore」に「local_settings.py」の１行を追加してください。

```:.gitignore
dj
__pycache__
staticfiles
local_settings.py 👈追加
db.sqlite3
*.py[co]
```


##（４）「settings.py」を編集する（４ステップ）
**(蛇足な部分がある可能性あり)**
![スクリーンショット 2019-06-27 19.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/18524342-d0c5-e4aa-d756-689f96c6f538.png)


###（４−１）ステップ１
下のコードを、settings.pyの**一番下**に貼り付けてください。
`"@@@@@@@@@@"`の部分は自分の**パソコンの**ユーザー名に変更してください。

```python:settings.py
#この上は省略してあります
STATIC_URL = '/static/'👈（静的ファイルがある方のみ）
STATIC_ROOT = os.path.join(BASE_DIR, 'kiite/static')👈kiiteの部分は自分のアプリ名（静的ファイルがある方のみ）

from socket import gethostname
hostname = gethostname()

if "@@@@@@@@@@" in hostname:
    # デバッグ環境
    DEBUG = True
#=====ここから...=====
    import pymysql
    pymysql.install_as_MySQLdb()

    DATABASES = {
        'default': {
            #'ENGINE': 'django.db.backends.sqlite3',
            #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
             "ENGINE": "django.db.backends.mysql",
             "NAME": "kiitedb",👈ここは人によって違う
             "USER": "root",👈場合によっては違う
             "PASSWORD": "root",👈場合によっては違う
             "HOST": "127.0.0.1",
             "PORT": "3306",
        }
    }
#=====...ここまでは、使用しているデータベースに置き換えてください。=====
    ALLOWED_HOSTS = []
else:
    # 本番環境
    DEBUG = True
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console': {
                'class': 'logging.StreamHandler',
            },
        },
        'loggers': {
            'django': {
                'handlers': ['console'],
                'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
            },
        },
    }

    # DB設定
    import dj_database_url
    PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
    db_from_env = dj_database_url.config()
    DATABASES = {
        'default': dj_database_url.config()
    }
    ALLOWED_HOSTS = ['*']
#この下には何もありません
```

###（４−２）ステップ２
`WSGI_APPLICATION = '<プロジェクトネーム>.wsgi.application'`を探して、その下に下記のコードを貼り付け

```python:settings.py
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES = {
    'default': dj_database_url.config()
}
```

###（４−３）ステップ３
`MIDDLEWARE`を探して、下の１行を追加してください。

```python:settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',👈この１行だけを追加
    'django.contrib.sessions.middleware.SessionMiddleware',

```
###（４−４）ステップ４
下のように変更（最初からなっている人も多いと思いますが、一応）

```python:settings.py
ALLOWED_HOSTS = ["*"]
```

##（５）「wsgi.py」を編集
![スクリーンショット 2019-06-27 19.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/18420423-011f-0f51-7fe2-eee5b56ece36.png)

「wsgi.py」を下記のコードに変えてください。**（追記ではなく、全変えです。）**

```python:wsgi.py
#この上には何もありません
import os
from django.core.wsgi import get_wsgi_application


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp7.settings')👈myapp7は自分のアプリ名に変更

application = get_wsgi_application()

from whitenoise.django import DjangoWhiteNoise
application = DjangoWhiteNoise(application)
#この下には何もありません
```

##（６）「Heroku CLI」をインストール
[ここからインストールしてください。](https://devcenter.heroku.com/articles/heroku-cli)
インストーラーを起動後、「OK」や「完了」を押して、次々に進んでいけば大丈夫だと思います。
![スクリーンショット 2019-06-27 19.37.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/b5f1c5c8-5e86-c80d-335e-d2a209a374c3.png)


##（７）デプロイ
![スクリーンショット 2019-06-27 19.48.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427946/97c40974-e37a-097c-d2f4-fc2b72e608d6.png)

下のコマンドをデプロイするアプリがある開発環境で順番に実行。
`myapp7`や`kiite`は適宜変更してください。

```:terminal
(dj)$ cd myapp7 👈外側のディレクトリに移動
(cd)myapp7 $ git init 👈「.git」ディレクトリが作成される
(cd)myapp7 $ git config user.name <自分の名前> 👈<>はいらない
(cd)myapp7 $ git config user.email *+*+*+@info.com
(cd)myapp7 $ git add -A . 
(cd)myapp7 $ git commit -m "First Django App, OK"
(cd)myapp7 $ heroku login 👈Herokuアカウントは事前に作成しておいてください
(cd)myapp7 $ heroku create kiite 👈kiiteは自由に変更（省略も可能）
(cd)myapp7 $ git push heroku master
(cd)myapp7 $ heroku ps:scale web=1
(cd)myapp7 $ heroku run python manage.py migrate
(cd)myapp7 $ heroku run python manage.py createsuperuser
(cd)myapp7 $ heroku open
```
終了

##参考サイト
- https://qiita.com/okoppe8/items/76cdb202eb15aab566d1
- http://makimakimakino.hatenablog.com/entry/2019/01/13/200729
- https://qiita.com/RyuSA/items/04f8f6a22370ca639ff9
- https://qiita.com/Shitimi_613/items/6627d0ce042d38b86893