Django+Postgres+DockerをHerokuにデプロイ

# はじめに
少し前に、[DockerでDjango+Postgresの環境でTodolist](https://qiita.com/maooz4426/items/c03dbcedcf0c4276f80c)を作ったのですが、今回はそれをHerokuにデプロイしてみました。

:::note warn
コンテナをデプロイする方法もあるらしいですが、今回はやっていません。ご了承ください。
:::

## GithubStudent
学生であれば、申請すればHerokuが月$13分の合計24ヶ月分無料で使えるようになります。詳しくは[こちら](https://jp.heroku.com/github-students)をご覧ください。

## そもそもHerokuとは
[Heroku](https://dashboard.heroku.com/)とは、Passと呼ばれるアプリケーションを実行するためのサービスを提供しているプラットフォームのことです.
>Pass
"Platform as Service"の略称です。アプリケーションの稼働に必要なネットワーク、OS、サーバー、ミドルウェアをプラットフォームとして提供しているサービスのことです。

>Iaas
"Infrastructure as Service"の略称です。サーバーやストレージやネットワークなどのインフラ環境を提供するサービスのことです。AWSやGCPはコレにあたります。

>Saas
"Software as Service"の略称です。ソフトウェアをクラウド上で提供し、利用できるサービスのことです。Office３６５とかがコレに該当します。

## デプロイの準備
### Heroku側
今回は、Herokuのアカウントは作成済みの状態で進めます。

まず、`New`と書かれている箇所を押し、`Create New App`を選択します。
![スクリーンショット 2024-05-24 22.48.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/ca1bb7c8-2de6-9ffb-316b-4d2e5449510e.png)

そこから、今回Herokuにデプロイするアプリケーション名を入力します。入力し終わったら`Create App`を選択します。
![スクリーンショット 2024-05-24 22.49.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/e16111c6-0fb9-1201-f6f4-5272da0422e3.png)

これでHeroku上に空のアプリケーションができましたが、ここからPostgerSQLの環境を作ります。
下の画像のようになっていると思うので、アプリ名の下の欄から`Resources`を選択して、画像中央右にある`Find more add ones`をクリックします。
![スクリーンショット 2024-05-24 22.51.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/a0de7c1a-48ee-26b3-6a5a-103a3160f1ad.png)

すると、いろいろなアイコンが出てくると思うので、そこから`Heroku Postgres`を探して選択します。
![スクリーンショット 2024-05-24 22.52.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/bc4ab348-e3e8-c94c-6f07-5034ed71bd22.png)

`Install Heroku Postgres`を選択します。
![スクリーンショット 2024-05-24 22.53.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b17832cd-9660-fa23-af5a-43bb008fc581.png)

`Add on plan`を画像のように`Essential 0`にします。
![スクリーンショット 2024-05-24 22.54.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/f94027ef-050a-c670-f4e6-158970e69704.png)

:::note
今回は、一番安いものに設定しています、自分のしたいことに合わせて選択してください。
今回のようにデプロイしてみたいだけなら、今回の設定で大丈夫だと思います。
:::

`App to provision to`で先ほど作成したHerokuのアプリ名を入力します。そこから、`Submit Order Form`を選択します。
![スクリーンショット 2024-05-24 22.55.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/379830a9-83e9-0c12-7466-53a9608e740b.png)

時間が経つと`Heroku Postgres`と書かれている部分が押せるようになるので、それを押します。
![スクリーンショット 2024-05-24 23.04.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/1974b8e9-47df-edce-204c-148e001fdb97.png)

下のような画像になるので、`View Credentials`を選択するとDBの情報が閲覧できるようになります。

![スクリーンショット 2024-05-24 23.06.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/7cd655b0-bfaf-2636-4226-85e5e00b5670.png)

![スクリーンショット 2024-05-24 23.10.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/f0c4c4d3-17fa-6128-1c97-7083e4793c37.png)

ここから、この情報を環境変数で設定します。
アプリ作成後に出てきた画面に戻り、`Setting`と書かれているところを選択し、`Reveal Config Vars`を選択します。

![スクリーンショット 2024-05-24 23.46.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/75aba6f8-29cf-5fc5-23a4-9fafc7cf1c54.png)

ここで環境変数を設定できるので、先ほど出てきたDBの情報を、`.envファイルに書いた内容と一致させながら入力します。
![スクリーンショット 2024-05-24 23.49.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/e9095a28-3d16-f14a-ca84-1fca78768c28.png)

>ここで入力する内容に困った方は、[こちら](https://qiita.com/maooz4426/items/c03dbcedcf0c4276f80c)の記事の`.env`の部分を参考にしてください。

:::note warn
今回は、DB情報での`Database`を`DATABASE_NAME`に入力しています。
:::

これで一旦Heroku側の設定は終わりです。

### Django側の設定
ここからDjangoの設定を変更していきます。

`requirements.txt`にHerokuのデプロイに必要なライブラリを記述します。
```requirements.txt
Django==4.1
psycopg2  
#ここから下を追加
dj-database-url
gunicorn
whitenoise
```
>`dj-database-url`
DBの接続情報を管理するのに役に立つライブラリ、正直どこで使ってるかわかりませんが書きました。

>`gunicorn`
djangoやFlaskなどのWSGIアプリケーションを動かすためのWSGI　HTTPサーバーのこと
>>`WSGI`
Web Server Gateway Interfaceの略
Webサーバー、アプリケーションサーバー、データベースサーバーの中継地点となり、リクエストの窓口となるものをいう。

>`whitenoise`
静的ファイルを提供を容易にするためのライブラリ
>ローカルでは、URIが`***static/test.png`となるが、リモートでは、`static/test.28487bbbe8b5.png`みたいにハッシュ値が挟まれるのでうまく静的ファイルを参照できないので、これを参照できるようにしてくれる。



`Setting.py`を編集します。
`ALLOWED_HOSTS`に`.herokuapp.com`を追加します。
```Setting.py
ALLOWED_HOSTS = [
    '.herokuapp.com',#追加
    '0.0.0.0',
    '127.0.0.1',
    'localhost'
]

```

`MIDDLEWARE`に`whitenoise.middleware.WhiteNoiseMiddleware`を追加します。
```Setting.py
MIDDLEWARE = [
    'whitenoise.middleware.WhiteNoiseMiddleware',#追加
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

```
Webサーバーでは、静的ファイルをすべて一つの箇所に集める必要があります。
そのために`STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')`を追加します。
```setting.py
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
```

次にアプリを実行した際に行われるコマンドを書いておく`Procfile`を書きます。
```Procfile
web: gunicorn todolist.wsgi --log-file -
```
コレを書くことで、gunicornでdjangoを動かすようにしています。


`runtime.txt`にherokuで動かすpythonのverを指定します。
```runtime.txt
python-3.9.19
```

## デプロイ

今回は、gitのリポジトリを使います。

https://github.com/maooz4426/TodoList-Django/tree/heroku

下の画面に移動して、repo name`でリポジトリと該当ブランチを選択します。今回は、Heroku用の設定を適応している`Heroku`というブランチを作ったので、それを使いました。

![スクリーンショット 2024-05-24 23.24.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/7acf15d1-17c8-704d-a03e-e03c47a5bae7.png)

![スクリーンショット 2024-05-24 23.27.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/d5f305b9-bafd-aaa4-1beb-3494d3994775.png)

ブランチの横にある`Deploy Bramch`を選択して、少し待ちます。

すると`view`というボタンが出てくるので、それを選択します。

![スクリーンショット 2024-05-24 23.28.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/a3f66300-b85c-31af-b952-e72022b2a4ba.png)

見れました。
![スクリーンショット 2024-05-25 15.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/bcbc5397-ddde-4d07-82c7-0bc1e75d703e.png)


## エラーが出て困った時
デプロイできてもアプリがクラッシュしている時があります。
そんな時は以下のコマンドでログを確認してください。

```
heroku logs --tail -a <あなたのapp名>
```
>-aは、-appの短縮形です。

# 最後に
コンテナをデプロイする方法もあるそうなので、どこかの機会でやってみたいと思いました。