初心者がFlaskのアプリをHerokuでデプロイする

# 概要と目的
　はじめまして、プログラミング初心者です。プログラミングを学習する上で、何か成果物を残すのは大事なことです。なので私は`Python`の学習の成果物として、`Flask`を用いたWebアプリを制作しました。
　制作したWebアプリを公開しようという事で、無料サーバの`Heroku`と`Git`によるリポジトリ操作について学びました。色々なサイトを参考にしたのですが、所々つまづくことがあったので、自分用にまとめた記事を作ることにしました。

### 目的

- Flaskの簡単なアプリを作る
- ローカルな仮想環境でFlaskのアプリを動かす
- HerokuとGitでデプロイする

### 実行環境
- 日時：2021/09/26
- OS：windows10
- Python 3.9
- Flask 2.0.1
- pip 21.2.4

# ①　FlaskでWebアプリを作る
　`Flask`と`Python`用の、軽量なウェブアプリケーションフレームワークです。同様のフレームワーク`Django`に比べて軽量で、最小限の機能で1から設計することが可能です。今回はサーバ公開をメインとして記述するので、本記事で`Flask`について多くは述べません。

　今回、使用するコードはこちら

```main.py
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/')
def index():
  res = {}
  res['comment'] = 'Hello World!'
  return render_template('index.html', res=res)

if __name__ == '__main__':
    app.run(debug=True)
```

```templates/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="../static/style.css">
  <title>MyApp</title>
</head>
<body>
  <h1>{{ res['comment'] }}</h1>
</body>
</html>
```

```static/css/style.css
body {
  background-color: gray;
}
```

　簡単に説明すると、`main.py`で`res`経由で`index.html`に文字を表示させる感じです。あとcssで背景色を水色にしてます。`Flask`については他記事や参考書を参照ください。ちなみに私は某Python専門オンライン学習サービスで勉強しました。

# ②　ローカル環境でFlaskを動かしてみる
　続いて、コマンドプロンプトを用いてローカル環境でFlaskを動かしましょう。

### 仮想環境を作る
　今後の為に、ライブラリ`pipenv`で仮想環境を構築しておきましょう。まだ`pipenv`をインストールしていない場合、コマンドプロンプトから`pip install pipenv`でインストールしましょう。
　`main.py`のあるディレクトリで仮想環境を構築するため、まずは`cd [当該ディレクトリ]`で移動しましょう。今回は`C:\Users\USERNAME\Downloads\myApp>`で環境構築します。
　準備が出来たら、以下のコマンドで仮想環境を作ります。

```
C:\Users\USERNAME\Downloads\myApp>pipenv shell
```

　色々表示されますが、`Successfully created virtual environment!`(仮想環境の作成成功)と表示されれば大丈夫だと思います。
　仮想環境が出来たので、必要なライブラリをインストールしましょう。

```
(myApp-hyHviofc) C:\Users\USERNAME\Downloads\myApp>pip install flask
```

　今回はFlaskだけの簡単なアプリなので、Flaskだけをインストールしました。
　これで環境は完成です。

### アプリを動かす
　ではアプリを動かしてみましょう。

```
(myApp-hyHviofc) C:\Users\USERNAME\Downloads\myApp>set FLASK_APP=main.py

(myApp-hyHviofc) C:\Users\USERNAME\Downloads\myApp>flask run
 * Serving Flask app 'main.py' (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://X.X.X.X:5000/ (Press CTRL+C to quit)
X.X.X.X - - [27/Sep/2021 00:52:48] "GET / HTTP/1.1" 200 -
X.X.X.X - - [27/Sep/2021 00:52:48] "GET /static/style.css HTTP/1.1" 200 -
```

　これでローカルサーバが動きました。ブラウザでURLに`localhost:5000`を入力すると、Webアプリが表示できるようになりました。なお、サーバは`Ctrl+C`で終了できます。

![localhost:5000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088977/80c589eb-5029-47f1-89dd-6524d106a6df.png)


　さて、これでアプリが動くことを確認できました。

# ③　必要なファイルを用意する

　あとはHerokuでサーバを立ち上げればいいのですが、そのために必要なファイルやライブラリがいくつかあります。

- gunicorn httpサーバ用のpythonライブラリ
- requirements.txt ライブラリの一覧
- runtime.txt　pythonのバージョン指定
- Procfile Heroku用のファイル

　まず、HerokuでFlaskアプリを公開する時、必要なライブラリ`gunicorn`があります。今のうちに仮想環境にインストールしておきましょう。

```
(myApp-hyHviofc) C:\Users\USERNAME\Downloads\myApp>pip install gunicorn
```
　サーバでは、必要なライブラリを記載したテキストファイル`requirements.txt`を用意します。エディタでいちいち書いても作れますが、今回は簡単に`pip`の`freeze`コマンドで`requirements.txt`出力させましょう。

```
(myApp-hyHviofc) C:\Users\USERNAME\Downloads\myApp>pip freeze > requirements.txt
```

```requirements.txt
click==8.0.1
colorama==0.4.4
Flask==2.0.1
gunicorn==20.1.0
itsdangerous==2.0.1
Jinja2==3.0.1
MarkupSafe==2.0.1
Werkzeug==2.0.1
```

　続いて、`python`のバージョンを記載したテキストファイル`runtime.txt`を用意します。テキストエディタで以下のように書きましょう。頭文字は小文字で、ハイフンを忘れないようにしましょう。

```runtime.txt
python-3.9.7
```

　最後に、`Procfile`というファイルを用意します。テキストエディタで以下のような文を入力して、ファイル名を`Procfile`(拡張子無し)にしてください。今回は`main.py`を実行するため以下のようになりますが、`アプリ名.py`で実行する場合は以下の文の`main`を`アプリ名`に変更してください。

```Procfile
web: gunicorn main:app --log-file=-
```

# ④　GitとHerokuのCLIをインストール
　必要なファイルの準備が終わりました。
　次はデプロイに必要な`Git`と`Heroku`を使えるようにしましょう。
　本記事では必要な物とURLを載せたので、まだインストールしていない方はリンクからインストールしましょう。

### Gitのインストール
　[Gitの公式サイトからインストール](https://git-scm.com/)しましょう。

### Herokuのアカウント作成
　[Herokuの公式サイトでアカウント作成](https://jp.heroku.com/)しましょう。
　アカウントができたら、[Heroku CLIのインストール](https://devcenter.heroku.com/ja/articles/heroku-cli)しましょう。

# ⑤　デプロイ！
　ではいよいよデプロイです。
　コマンドプロンプトでアプリのディレクトリに移動しましょう。

　まず、コマンドプロンプトから`heroku`にログインする必要があります。

```
C:\Users\USERNAME\Downloads\myApp>heroku login
heroku: Press any key to open up the browser to login or q to exit:
```

- `heroku login`　herokuにログインする

　ここでエンターキーを押すと、ブラウザで`heroku`のログイン画面が表示されます。ログインできればOKです。

　続いて、`heroku`のアプリフォルダを作成しましょう。
　

```
C:\Users\USERNAME\Downloads\myApp>heroku create qiita-test-myapp
```

- `heroku create [アプリ名]`　アプリの作成

　このコマンドで作成できます。なお、名前に指定できるのは小文字の半角英語と数字とハイフンだけのようです。また、既に使用されている名前は使えません。今回は`qiita-test-myapp`という名前にしました。
　実行して`done`と表示されていればOKです。

　続いて、`Git`でファイルを`Heroku`に送ります。

```
C:\Users\USERNAME\Downloads\myApp>git init
C:\Users\USERNAME\Downloads\myApp>heroku git:remote -a qiita-test-myapp
C:\Users\USERNAME\Downloads\myApp>git add Procfile static templates main.py requirements.txt runtime.txt
C:\Users\USERNAME\Downloads\myApp>git commit -m 'memo'
C:\Users\USERNAME\Downloads\myApp>git push heroku master
C:\Users\USERNAME\Downloads\myApp>heroku open
```

- `git init`　gitの準備
- `heroku git:remote -a [アプリ名]`　Gitとつなぐherokuのアプリ名の指定
- `git add [ファイル名]`　必要なファイルの追加

　ファイル名に複数のファイルを載せることもできます。また、`.`とすると、ディレクトリ内の全てのファイルを追加できますが、今回は仮想環境で生じた`Pipfile`があり、これは追加しないため以下のように実行しました。

- `git commit -m [コメント]`　変更のコミット

　コミットにはコメントを付けます。うまく使えば変更ログとかがわかりやすくなります。

- `git push heroku master`　変更のプッシュ

　これがERRORなく実行できれば、デプロイは成功です。

- `heroku open` Webアプリを表示する

　ここまで成功していたら、ブラウザでWebアプリが表示できると思います。
![qiita-test-myapp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088977/6e42cffe-051a-f5f7-6e0e-84c4ad099ca2.png)


　表示できました！
　私が最初にデプロイしようとした時は、pushでエラーが表示されたり、CSSが反映されなかったり等のエラーがありました。ですがpythonのコードや必須ファイル、コマンドが正しくできていれば解決できるケースが多いのではと思います。Webアプリを作ってみたら、デプロイしてみましょう。

## 参考文献
　以下のサイトを参考にさせていただきました。ありがとうございました。

- [プログラミング日記：HerokuでFlaskアプリを公開するまでの手順](https://plumfield56.com/python/herokuflask/)
- [スタビジ：herokuを使ってPythonのflaskで作ったアプリケーションをデプロイする方法と注意点！](https://toukei-lab.com/heroku-python)