オリジナルKdB(科目検索)を作ってみよう -6- 本番環境Herokuにデプロイ編

### これまでの記事
- [オリジナルKdB(科目検索)を作ってみよう -1- Node.jsセットアップ編](https://qiita.com/tkkrr/items/2f0d93b6d0c758a88037)
- [オリジナルKdB(科目検索)を作ってみよう -2- パース編](https://qiita.com/tkkrr/items/d8a87b4f598b1b107266)
- [オリジナルKdB(科目検索)を作ってみよう -3- データで遊ぶ編](https://qiita.com/tkkrr/items/8c0f66312212420114a0)
- [オリジナルKdB(科目検索)を作ってみよう -4- Express.jsでWEBアプリことはじめ編](https://qiita.com/tkkrr/items/5cafa77c104b11d76a16)
- [オリジナルKdB(科目検索)を作ってみよう -5- Express.jsでWEBアプリ整形編](https://qiita.com/tkkrr/items/9ea97ee9b2823e3a381e)

### 前回の要約
- パースした情報をExpress.jsで整形した
- Express.jsと相性のいいテンプレートエンジン**Pug**を書いた

<img width="1241" alt="スクリーンショット 2019-02-22 16.11.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/3d0c6b57-d3a9-1be1-4166-f9068a2f9771.png">

# この記事を読む前に
この記事はシリーズものです。前回の記事を読んである前提で話を進めるので注意してください。
また、ある特定の人にしかわからない単語が出現する可能性が高いです。あらかじめご了承ください。

### この記事での開発環境
- MacOS 10.14.3
- Visual Studio Code 1.31.1
- Node.js LTS 10.15.1

# 今回やること
- 本番環境であるHerokuにデプロイ(配置)する

キーワード **Heroku, Git, 本番環境**

# いよいよ公開...ｯ !!
それではいよいよ作ったWebアプリを公開します！
公開とはなんぞやと言う人のために簡単な説明を...

![アセット 1.png](https://qiita-image-store.s3.amazonaws.com/0/245014/f70701ed-af11-d237-6f8c-6ef1eeb66faa.png)
![アセット 2.png](https://qiita-image-store.s3.amazonaws.com/0/245014/54e768ff-6d59-e02b-926c-0166621bbc68.png)
![アセット 3.png](https://qiita-image-store.s3.amazonaws.com/0/245014/5d0bcbb3-af2c-9b1d-e567-8644fd369980.png)
![アセット 4.png](https://qiita-image-store.s3.amazonaws.com/0/245014/d5beeb08-aa7e-7585-24e3-08c257258bb7.png)

**どこからでも参照できるネットワークにデプロイすること = 公開** ということになります！(厳密にはもう少し掘り下げる必要がありますが、ここでの説明は割愛させていただきます。)

今回は、どこからでも見れるネットワークを提供するサービスとして[**Heroku**](https://jp.heroku.com)というものを使います。

<img width="1440" alt="スクリーンショット 2019-02-25 15.02.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/22a45969-9c90-7603-6566-e5933199852c.png">

Herokuは無料で始めることができ、多機能で簡単に公開ができる便利なサービスです。Node.jsのほか、PythonやRuby,PHPでなどの多様な言語に対応しており、作ったアプリケーションに少し追加記述をするだけで公開することができます。

それでは始めていきましょう！

# Herokuにサインアップしよう
まずはHerokuにアカウント登録してHerokuにアプリケーションをデプロイできるようにします。
次のリンクからサインアップしましょう → https://signup.heroku.com/login

# Herokuのツールをダウンロードしよう
サインアップしたら、今度はツールをダウンロードしてきます。Herokuへのデプロイを簡単にしてくれる便利なツールなのでチャチャっと手に入れましょう。

ダウンロードはこちらから → https://devcenter.heroku.com/articles/heroku-cli

手っ取り早くやりたい人は以下のコマンドをターミナルで実行すればOKです。

```shell
$ curl https://cli-assets.heroku.com/install.sh | sh
```

※npmからインストールすることもできますが、公式が非推奨にしているので直接ダウンロードするか、上記のように`curl`を使ってインストールするようにしましょう。

```shell
$ heroku --version   # 入っているか確認
heroku/7.22.0 darwin-x64 node-v11.9.0   # こんな感じで表示されればOK!
```

# 作ったアプリケーションの修正をしよう
Herokuでアプリケーションが動くように少し修正を加えます。

#### app.js
まずは`app.js`を修正しましょう。

```javascript:app.js
const app = require("express")();
const getParseData = require("./index");

const dataArray = getParseData( "kdb_jis.csv", "shift_jis" );

app.set('port', (process.env.PORT || 3000)); // 追記
app.set("view engine", "pug");

app.get( "/", (req, res) => {
    res.render("html.pug", {state: dataArray ,word: "全検索"});
});

app.get( "/:word", (req, res) => {
    const state = [];
    const matchReg = new RegExp(req.params.word);
    dataArray.filter( (data) => {
        return data[1].match(matchReg) 
    }).forEach( (element, index) => {
        state.push(element); 
    });
    res.render("html.pug", {
        state: state,
        word: req.params.word
    });
});

app.listen( app.get('port') );  // 記述修正
console.log("server started!!");
```

では解説。

```javascript
app.set('port', (process.env.PORT || 3000));
```
ここでは、Herokuが指定したポートを使うようにjavascriptに命令しています。Herokuが使うポートは環境変数に格納されているので、`process.env.PORT`で環境変数を参照します。

ローカルで起動した場合は(環境変数`$PORT`いじってない限りは)ポート番号3000番で起動するように記述していますので、これまで通り http://localhost:3000/ でアクセスできるはずです。

```javascript
app.listen( app.get('port') )
```

`app.get('port')`は先ほど書いた`app.set('port', ~ )`に対応しています。環境変数に関する細かい説明は長くなるので割愛します。

#### Procfile
次はHerokuに命令するためのコマンドを書いたファイルを追加します。
ファイル名は **`Procfile`**です。

```:Procfile
web: node app.js
```

今回はNode.jsで実行するので`web: node app.js`と指定します。例えば Ruby on Rails ならProcfileの中身は`web: bundle exec rails server -p $PORT`のようになります。

#### .gitignore
```:.gitignore
node_modules
```
.gitignoreの追加はオプションですが、**作っておいたほうが今後絶対に楽です**。これはHerokuにデプロイするために使う`git`コマンドが参照するファイルで、Finderやファイルエクスプローラには表示されません。ですが、今後開発を進めていく上で極めて重要なファイルになる可能性が高いです。オプションではありますが追加しておきましょう。

これでファイル修正は終了です。さて、次はいよいよデプロイです。

# Herokuにデプロイしよう
ターミナルを開いて以下のコマンドを実行します。

```shell
$ Heroku login
```

そしたら指示に従ってログインしましょう。この操作は一回限りで大丈夫です。今後別のアプリをデプロイするときにこのコマンドを入力する必要はありません。(別アカウントでデプロイするときや、Heroku-cliを再インストールしたときは別です。)

ログインしたら次のコマンドを入力します。

```shell
$ heroku create
```

これで新しくWebアプリケーションを置くスペースをHeroku上に作りました。ブラウザからHerokuにログインしてダッシュボードで確認すれば実際に作成されていることがわかると思います。なお、この段階ではまだ中身が空っぽです。

次のコマンドを順番に実行してデプロイ準備を済ませましょう。

```shell
$ git add -A   # Gitでステージングします
$ git commit -m "initial commit"   # Gitでコミットを残します
```

`git`コマンドについて何も説明していませんが、調べればすぐに出てくるのでググってみてください。オススメのサイトを以下に記しておきます。

- [サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)
- [新入社員による新入社員のためのGit](https://qiita.com/shunhikita/items/9b909b566d1b0a263519)

また、Gitには便利なGUIツールがあります。[**Sourcetree**](https://ja.atlassian.com/software/sourcetree) や [**GitKraken**](https://www.gitkraken.com) は特に使いやすいのでオススメです。CUIではGitツリーを魔法みたいに操作できる黒魔術も使えますが、正直GUIツールで十分なので検討しましょう。

最後にデプロイです！

```shell

$ git push Heroku master   # デプロイします！

Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
...

remote:        Released v5
remote:        https://mykdb.herokuapp.com/ deployed to Heroku
remote: 
remote: Verifying deploy... done.    # 成功した！！！！！
To https://git.heroku.com/mykdb.git
   bdd47a4..b79cfe0  master -> master
$
```

特にエラーも表示されず、成功したらデプロイ成功です！！
それでは公開されているか確認しましょう。

```shell
$ Heroku open
```

<img width="1440" alt="スクリーンショット 2019-02-25 15.46.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/245014/38e18d7d-a39c-4071-ef67-d529dd687c19.png">

https://〇〇.herokuapp.com/ で見ることができれば成功です！公開できました！
〇〇の部分は変更できるので。以下のコマンドから好みの名前を指定しましょう。

```shell
$ heroku rename 変更後の名前   # 例えば私の場合は $ heroku rename mykdb
```

https://mykdb.herokuapp.com/

先約がいなければ自由に変更することができます！

# 公開できた！！！
これにてシリーズは一旦終了です！アプリケーションはここからさらに拡張できますのでオリジナルKdBを極めていってください！

ちなみにアプケーションを修正した後に再デプロイする場合は、以下の3つのコマンドを入力すればOKです。

```shell
$ git add -A
$ git commit -m "変更点を記述"
$ git push heroku master
```

長くなりましたがありがとうございました！
これを読んでくれたユーザの皆さん！作ったアプリケーションをぜひ紹介してください！
どんなアプリケーションができるのか楽しみです！

#### ※lambda系サービス(FaaS)に移植する記事を書きました↓

- [オリジナルKdB(科目検索)を作ってみよう -番外1- FaaS下準備編](https://qiita.com/tkkrr/items/077dd30091b24e64b86b)
- [オリジナルKdB(科目検索)を作ってみよう -番外2- AWS Lambda編](https://qiita.com/tkkrr/items/e67227bcb15c1a08bb2b)


## 今回のあとがき
シリーズ終了。さてさて今回のあとがきはHerokuのようなサービスについての紹介です。
Herokuは「動的Webアプリケーションの公開」ならまずはじめに挙げられるサービスと思います(だって無料ですし)。小さなアプリケーションを少ない労働力でささっと公開できるのでとても便利です。

HerokuのようなNode.jsのコードを書くだけでささっと公開できるようなサービスのことを**PaaS**(Platform as a service)と呼びます。本来Webアプリケーションを公開するためには

- サーバ用のコンピュータを用意する
- OSをインストールする
- 外部公開用にパブリックIP(グローバルIP)を用意する
- Apache, NginxのようなWebサーバソフトウェアをインストール
- Apache, Nginxに必要なモジュールや設定を記述
- ドメイン・SSL証明書を用意する
- Node.jsでアプリケーションのコードを記述する
- デプロイして公開

などなど... 面倒くさいことが山ほどあります。HerokuのようなPaaSはこれらをあらかじめ用意してくれているので最後の2つだけをやればいいということです。楽ですね。ですが、もちろん低レイヤーでの問題が起きた場合、私たちにはどうにもできません。その場合はPaaS提供側が復旧するまで待つしかありません。こればっかりは便利さとのトレードオフです。

個人的ではありますが、Herokuの苦手なところとして無料枠ではスリープ機能があります。これは1時間アクセスがなかったときにサーバをスリープさせるというものです。もちろんHerokuからしてみればコスト削減になるのでいいのですが、スリープからの復帰時には30~40秒待たされます。そのため、「Webアプリケーションで稼ぐぞ！」みたいなケースにはあまりオススメできません。素直に課金しましょう。

私個人としてはBFF(Backend For Frontend)やJAMStackのアーキテクチャを採用してフロントエンドとバックエンドを切り分けて考えるほうが好きです。フロントエンドはフロントエンドに、バックエンドはバックエンドに注力できます。そのため、このシリーズのようにバックエンドがPugなどを使ってデザインが〜なんてことは発生しなくなりますし、フロントエンドもバックエンドも双方に縛られることなく自由なフレームワーク選択や言語選択ができるようになります。フルスタックなフレームワークを選択することが無難ではなくなってきているのです。

ネットワークの高速化や通信機器の多様化によって現在のWebアプリの在り方は大きく変わってきています。それに対応するようにとんでもない速さでWeb開発技術が生み出されては枯れていきます。その周期は10年よりもずっと短いです。速すぎるんですよまったく。

これからWebエンジニアになろうと思っている人間がここにおるので！！！
誰かアドバイスをくださいな！！！

それではまた

#### 参考サイト
- [Welcome! - The Apache HTTP Server Project](https://httpd.apache.org)
- [Nginx](https://nginx.org/en/)
- [BFF（Backends For Frontends）超入門](https://www.atmarkit.co.jp/ait/articles/1805/18/news022.html)
- [JAMstack - クライアントサイドJavaScript、再利用可能なAPI、予めビルドされたマークアップによるモダンなWeb開発アーキテクチャ](https://qiita.com/ossan-engineer/items/4fe0e3e388f510bd5c68)
- [JAMstack](https://jamstack.org)