Flask+gunicornでHerokuにデプロイ

# 本題の前に
初めてのアドベントカレンダー13日目の記事です。折り返し地点となります。
ご参加いただいた方々、本当にありがとうございます！
記事書いたの本当に初めてですか？と冷や汗かきながら読ませてもらってます。
経験者の方々はさすがの記事です。毎日勉強させていただいてます。
駆け出しエンジニアの記事ですが、温かい目で見ていただきますと幸いです。

# 概要
ハッカソンでよくお世話になっているHeroku。
分かりやすく、無料で使えるのが学生にとてもありがたいポイントです。
筆者もよく使いますが、gunicornのパスの書き方,master以外のブランチからのデプロイ等、毎回いろいろと悩まされます。
というわけで記事の初挑戦をしつつ、備忘録がてら書くことにしました。

# 対象読者
・FlaskでWebアプリ作ったけどどうデプロイしようか調べている人
・gunicornで、ルートディレクトリ直下以外にapp.pyがあるときのパスの書き方が分からない人
・別ブランチからどうやってherokuにデプロイするべきか調べている人

# 環境
Windows10
Python 3.9.4
Heroku 7.59.1

# 準備
Herokuのアカウントの作成
https://jp.heroku.com/home

HerokuCLIのインストール
https://devcenter.heroku.com/articles/getting-started-with-java#set-up

をそれぞれ済ませてください

# ローカル環境でテストするまで
###Pythonで仮想環境の作成
作成は必須ではないですが、環境管理がしやすくなるので私はハッカソンごとに毎回作成しています。

```
#仮想環境の作成
python -m venv .venv 

#環境に入る(Windowsの場合)
./.venv/Scripts/activate
#環境に入る(Macの場合)
source .venv/Scripts/activate
```

参考記事:https://messefor.hatenablog.com/entry/2020/08/22/181519
Pythonの仮想環境作成について分かりやすく書かれています。

###pip install 
必要なものを導入

```
pip install flask
pip install gunicorn
```

###フォルダ構成
以下の構成で作っていきます。

```
root/ #開発しているディレクトリ
├.venv/ #仮想環境作ったら自動で出来る 
├src/
|  ├tamplate/
|  |    └index.html 
|  └main.py
├heroku.yml
├requirements.txt
└runtime.txt
```

フロントとなる部分です。

```html:index.html
<html>
    <head></head>
    <body>
        <p>Hello World!</p>
    </body>
</html>
```

アクセスしたらindex.htmlを返すというシンプルなサーバー。

```python:app.py
from flask import Flask,render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template("index.html")

if __name__ == '__main__':
    app.run()

```

Herokuで動かすためのymlファイルです。
--chdirはアプリの位置を表しています。今回の場合だと、rootのsrcのmainが始まりだよということです。
もしmain.pyのファイルがapp.pyの場合は、以下のmainの部分をappに変えてください。

```yml:heroku.yml
build:
  languages:
    - python
run:
  web: gunicorn --chdir src main:app --log-file - 
```

追加でインストールするライブラリ一覧です。
pip freezeと打ち込んで一覧を作るのが楽です。

```requiremets.txt
click==8.0.3
colorama==0.4.4
Flask==2.0.2
gunicorn==20.1.0
itsdangerous==2.0.1
Jinja2==3.0.3
MarkupSafe==2.0.1
Werkzeug==2.0.2
```

Pythonのパージョンを記述するファイルです。
Tnsorflow等を使っている場合、Pythonのバージョンによっては動かないことがあるので、適宜書き換えてください。

```runtime.txt
python-3.9.4
```

### ローカルホストでのテスト
main.py
以下のような記述が出たら、localhost:5000にアクセスして確かめてみてください。
http://127.0.0.1:5000/ からリンクを開くと、サーバーエラーで見られないことがあります。

```app.pyの実行
> python src/main.py

 * Serving Flask app 'main' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
```

動きましたね！
![hello.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349246/f87866e5-0a1c-906f-d022-ccf057ae0189.png)

#デプロイまで
### Herokuにログイン
Herokuにログインしていきます。loginするかと聞かれるので、enterを押して進み出てきた画面のボタンを押せば大丈夫です。

```
>heroku login
heroku: Press any key to open up the browser to login or q to exit: 
```

### heroku create
Heroku上にアプリケーションを作ります。
udon-flaskの部分は好きに変えてください。
指定しなければ適当に名前が決定されます。

```
>heroku create udon-flask
Creating ⬢ udon-flask... done
https://udon-flask.herokuapp.com/ | https://git.heroku.com/udon-flask.git
```

ローカルとHeroku上に作成したアプリケーションをつなげます。
udon-flaskの部分を先ほど作成したアプリケーション名に変えてください。

### heroku remote
```
>heroku git:remote -a udon-flask
set git remote heroku to https://git.heroku.com/udon-flask.git
```

コンテナの作成。
アプリケーション上でコードを動かすための箱を作るイメージです。

### heroku container
```
>heroku stack:set container
Setting stack to container... done
```

### gitコマンド
おなじみgitコマンドでデプロイしましょう。
git push herokuの後のmainはデプロイするブランチ名です。
mainの内容をHerokuに上げるという意味です。

```
>git add .
>git commit -am "comment"
>git push heroku main 
```

※以前はgit push heroku masterで動いてましたが、Githubのデフォルトブランチ名が変わっているためお気を付けください。
最初にデフォルトブランチ名をmasterにしている場合は、git push heroku masterで出来ます。

https://www.publickey1.jp/blog/20/githubmainmastermain.html

※デプロイ用のブランチなどを作成している場合、そこからherokuのmainに上げたいことがあります。
その時は以下のように記述してください。
コロンの左側がデプロイするブランチ名、右側がデプロイ先のブランチ名になります。

```
>git push heroku deploy:main
```

### heroku open
無事にデプロイ出来たら以下のコマンドで開いてください。

```
>heroku open
```

大体初回のデプロイはエラーを吐くので、そういうときは以下のコマンドです。
H14などのエラーが出るので調べつつ、ご自身のアプリケーションを見直してみてください。

```
>heroku logs --tail
```


#あとがき
gunicornの--chdirや指定ブランチからデプロイする方法は、ハッカソン当時必死に調べて解決した記憶があります。
困っている方々の参考になれば幸いです。
これからもHerokuで困ったことがあればここに追記していくことにします。
アドベントカレンダーは明日から後半です。
担当の皆様もよろしくお願いします！