Bottle製のアプリをHerokuへデプロイする方法

# Introduction

## きっかけ
ふと自分自身のサービスを作成してみたくて、Webアプリをインターネットにデプロイしてみようと思いました。普段の仕事でAWSを用いた業務アプリはいくつも作ってきました。しかし個人アプリ程度[^1]でAWSを使うのもどうか？と考え、AWSを使わず(なるべく安価で)構築してみようと考えました。

とかなんとか考えて作業をしていくわけですが、作業をしていく中でだんだんとこの選択が愚かしいことだったと理解していきます。結論から言うと、Webの世界の茫漠さとAWSの圧倒的な便利さに驚嘆するわけなのですが、この時の自分はわかっていませんでした。[^2]

なお今回の記事は三部作となっております。

WebサイトとWebアプリの違い
Webアプリの開発(ローカル) 
Webアプリの公開(Heroku) <-イマココ

です。


本記事の内容において上記の解説は省略しております。あらかじめご了承ください。

なおWebアプリとWebサイトに関する ~~未熟さ、~~ 当時の知識レベルはこちらの記事にまとめました。

https://qiita.com/Senple/items/cbf75c31e1816aed9efa

なお、要約すると下記のように認識しております。
>Webサイト： ブログのようなもの。事前に作成した文章をWeb上でまとめたもの。QiitaもWebサイトですね。Webアプリではありません。
Webアプリ： ユーザーの入力した内容をサーバー側で処理して値を返すもの。例えば電卓のようなもの。
完全な定義は自分もわからないです。詳しい方教えてください。

今回Herokuに載せるWebアプリはこんな感じです。

![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262742/ddf251d7-ab88-36ba-7473-22797da8d4cf.gif)


https://qiita.com/Senple/items/61acaa07fd2b52cb2f2d

BottleとVueCLIを用いて作成しました。
ローカルで動くBottleとVueJSで作成したアプリの詳細はこちらをご覧ください。



ローカルアプリを作成しつつ、サーバー周りも色々と調査しておりました。
調査内容はWebサイトとWebアプリの記事の中で書いた通りで、結論としては**Heroku**を用いました。
アカウント自体は3年ほど前に作成したものがありましたので、そちらを利用しました。当時のHerokuに関する理解状況はひどいものですが、記事が残っていましたのでこちらに掲載しておきます。**今回の記事とはなんの関連もありません。**

https://qiita.com/Senple/items/ece50a1fb29c748bd3ab


Heroku公式からデプロイ手順は出ておりますので、こちらをご覧いただくと一連の流れを理解しやすいと思います。自分はこれを見つけるまで時間がかかったので、試行錯誤しました。

https://devcenter.heroku.com/ja/articles/getting-started-with-python


なおコマンド一覧は付録として末尾に載せておきます。[^3]

## 今回の記事のお品書き
### 事前知識の共有
前提知識
- Gitに対するある程度の理解。
- Pythonに対するある程度の理解。
- Webフレームワークに対するある程度の理解。
- クラウドに対するある程度の理解。

## 自己紹介
![smile.jpg](https://qiita-image-store.s3.amazonaws.com/0/262742/38a82ae5-98e6-8d78-b461-3d14024af15d.jpeg)

[自己紹介ページ](https://qiita.com/Senple/items/b47374e68e4d8d26d0cb)

### 環境情報

```terminal:環境情報
macOS Monterey ver:12.2
vue 2.6.14
@vue/cli 5.0.4
node v16.8.0
npm 8.6.0
Python 3.9
```

最近はPipenvを使っています。
Pipenvに関する詳細は、こちらの記事がわかりやすかったので、リンクを貼っておきます。(古い記事ですのでご注意ください)
要約すると仮想環境でいい感じにライブラリを管理してくれるバージョン管理システムです。

https://www.m3tech.blog/entry/python-packaging#%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E7%AE%A1%E7%90%86%E3%81%AB%E4%BD%BF%E3%81%86%E3%83%84%E3%83%BC%E3%83%AB


Cf.) Python2系とかPython3系の意味が分からない人へ！
Pythonには2系と3系があって、最近始めた人ならほとんどPython3系だと思います。一応バージョンを確認する方法を記載しておきます。
MacOSに入っているターミナル(Terminal)でPythonのインタラクティブ(対話)モードを起動すればバージョン情報が表示されます。

```
$ Python
> Python 3.9.0 (default, May  4 2022, 01:10:11) 
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
```
インタラクティブモードを辞めるには*exit()*を入力しましょう！


# Let's Start

今回の記事は、JupyterLabではなく、VSCode上での実装です。

## Herokuに載せてみた。

### distをgitignoreから除去する。
やること：distをgitignoreから取り除く。
ローカルで動いたアプリならば、gitignoreからdist/を取り除けばOKです。

後で気づいたんですが、参考にしていたQiita記事の中に、この点に触れている記事もありました。
参考としてURLリンクを貼っておきます。

https://qiita.com/Nonta0605/items/5d8fa9a8eda9b3b7bc33#1-dist%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E4%BD%8D%E7%BD%AE

### ファイルのディレクトリ構造のこと
今回作成したWebアプリのディレクトリ構造は下記のようになっています。

```
qiita_test
  ├─backend(Bottleで作成する内容)
  ├─frontend(Vueで作成する内容)
  ├─Pipfile(Pipenvのバージョン管理)
  ├─Pipfile.lock(Pipenvのバージョン管理)
  ├─Procfile(Herokuデプロイ用)
  └─README.md(Githubでの管理用)
```

ここに至るまでの経緯などは下記の記事をご覧ください。

「ローカルで動くBottleとVueJSで作成したアプリの詳細はこちらをご覧ください。」

https://qiita.com/Senple/items/61acaa07fd2b52cb2f2d

```Procfile:
web: python backend/main.py
```

ここのmain.pyまでの経路は、上のディレクトリ構造次第です。
要するに、現在のディレクトリと実行したいディレクトリの位置にも依存する可能性があります。
今回の例は

```zsh:Terminal
python backend/main.py
```

https://devcenter.heroku.com/ja/articles/procfile#procfile-naming-and-location

### Portの話

この辺はWebで調べた通りにやっています。詳しいことはよくわかっていません。

```Python:app.py
app.run(host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
```

https://qiita.com/sgigagaeru/items/d0bffd18d1644d292b3d

>Herokuでは、どのポート番号でリッスンするかは動的に決まり、そのポート番号は環境変数PORTに格納されます。
そのためos.environ.get("PORT", 8080))でポート番号を指定します。
>
> Herokuでは、PORTに必ず値が設定されるので、デフォルト値の8080を記載する必要はありません。os.environ.get("PORT")で十分です。
しかしそうすると、ローカルで試験する際に、必ずPORTに値を設定しなければならず面倒です。デフォルト値の8080も記載しておいたほうが便利でしょう。

(言い訳)
あれ、前回と比べて今回の記事短くね？って思った方。
違うんです。自分は本来この記事程度の長さを想定して執筆したんです。
蓋を開けてみたら、前回の記事のあの分量です。

https://twitter.com/Semple_smile/status/1530422934762061824?s=20&t=2ALD2J1yP4wgxPsXGZIN_g

~~執筆しながらキレてます。~~ 嘘です。
勉強楽しいです。Web開発楽しいです。

# To be Continued
## 終わりに
今後もTwitterでこのようなWeb開発を発信していきます。興味があったらご覧ください。 ~~大抵はくだらないことです。~~

[Sempleのツイッター](https://twitter.com/Semple_smile)


## 今回のWebアプリには関係ないこと
### HerokuでのVueアプリのBuild
VueCLIのWebアプリだからといって、HerokuのBuildpackの準備等は不要でした。理由はPythonでVueにアクセスするから。(自分と同じようなトラブルにならないために書き記しておきます。)

Buildpackは、Herokuが勝手に作成したものだけで十分です。
中を覗くと、`heroku/python`となっています。

https://devcenter.heroku.com/ja/articles/buildpacks#using-an-official-buildpack

なおBottoleと関係なく、VueCLIのアプリをデプロイする際には、こちらをご覧ください。

https://zenn.dev/ryuu/articles/vueapp-deployto-heroku

https://cli.vuejs.org/guide/deployment.html#heroku

関係ない方は開いてはいけません。余計混乱するのみです。(実体験)


## Herokuコマンド一覧
### Webアプリ作成
HerokuのWebアプリを作成する方法(ここでは`heroku-sample`)
`heroku-sample`という入れ物に、現在のディレクトリのmasterブランチにあるソースコードをpushします。

`git push heroku main`
`git push heroku master`
のどちらか一方を利用する。

```zsh: Terminal
$ heroku apps:create heroku-sample
$ git push heroku master
```

https://devcenter.heroku.com/ja/articles/git#deploy-your-code

この時にすでに存在している名前と同一の名前で指定すると、作成できない。
なお、何も指定しないと、任意の名前でWebアプリが作成される。

```zsh: Terminal
$ heroku create
$ git push heroku master
```


### dyno関係のコマンド

https://devcenter.heroku.com/ja/articles/dynos#cli-commands-for-dyno-management

dynoを起動させるコマンド
```zsh: Terminal
$ heroku ps:scale web=1
```

dynoを終了させるコマンド
```zsh: Terminal
$ heroku ps:scale web=0
```

dynoの状態を確認するコマンド
```zsh: Terminal
$ heroku ps
```

### ログ確認

https://devcenter.heroku.com/ja/articles/logging#real-time-tail

herokuでリアルタイムログを見る方法。

```zsh: Terminal
$ heroku logs --tail
```


## 参考記事

[^1]: 当然円安の影響もあります。
[^2]: 知識のなさって怖いですよね。根拠のない自信を恨めしく思いました。（なお後悔はしていません）
[^3]: 正確には、自分が今後見返すためです。