個人開発でウェブアプリのベータ版をデプロイするときの備忘録

**@kenmaro**です。
普段は主に**秘密計算、準同型暗号などの記事について投稿しています**。
秘密計算に関連するまとめの記事に関しては以下をご覧ください。

> - [秘密計算エンジニアを始めて２年半が経った。](https://qiita.com/kenmaro/items/48059dd60f79e80f5ef8)
> - [秘密計算エンジニアを始めて3年が経った。](https://qiita.com/kenmaro/items/a1d90a074d552b7bf886)


今回は、秘密計算に関する記事ではなく、
個人開発で取り組んでいることについてまとめます。


## 概要


#### 個人開発で作っているウェブアプリのベータ版デプロイ時の備忘録
今回は、私が行っている個人開発における、
**サービスの本番環境へのデプロイメントで勉強になったこと**を備忘録がてらまとめていこうと思っています。

デプロイメントはいろいろなやり方があると思いますし、
対象とするユーザの規模であったり、企業で製品としてデプロイする時と、
個人開発としてベータ版の提供を考えてデプロイする時では構成（の規模）が大きく異なるかと思います。

#### （多分）対象となる読者

今回は、あくまでも
**個人開発、とりわけベータ版の提供開始を実施するための本番環境へのデプロイ**
を対象としていることをご了承ください。
また、webappに関してのデプロイは初めてだったため、いろいろとナイーブな箇所があるかもしれませんが、
その点も温かい目で見ていただけると幸いです。

しかしながら、**今回の構成はいろいろと使いまわせることも多い**(と思います)ですし、
仮にサービスが拡大したときのスケーリングなども比較的組み込みやすいように構成した（つもり）ですので、
**個人開発を行っているエンジニアの方**
にはある程度参考になるのかなと思っています。

## 記事の構成

以下のような流れでまとめていきます。

- **サービス構成の説明**
- **必要だったタスクのリストアップ**
- **各タスクの所要時間**
- **想定されるランニングコスト**
- **全体の感想**
- **ハマった項目リストアップ**
- **役に立った記事へのリンク**


## 今回提供をしようとしているサービスの構成
あくまでも今回は個人開発ウェブサービスのベータ版デプロイのシステム構成ですので、
サービスの内容については割愛することにします。
提供開始後に、サービスの内容についてまた宣伝しようかと思っています。

以下が簡単ではありますが、サービスのシステム構成です。
![Screen Shot 2022-05-22 at 18.26.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/9c9e2346-afa6-6f9e-11bf-2fd17f1de519.png)


## 必要だったタスク

上の構成を達成するために、大まかにだいたい以下のようなタスクが発生しました。

0. **（ランニングコストなどの）調査**
1. **フロントエンドのvercelへのデプロイ**
2. **バックエンドのECSを用いたデプロイ**
3. **お名前.comでドメインの取得**
4. **ACM、Route53、NLB、TargetGroupを用いたバックエンドのHTTPS化（TLSプロトコルの有効化）**
5. **データベースのバックアップ機構の作成**
6. **全体の接続確認**


## デプロイするのにかかった時間

私の経験としては、AWSについてはいろいろと触った経験は数年単位であるものの、
個人開発などで全体を一人でデプロイしたことはない、くらいのスタートラインでした。

この状態から、結論としてはデプロイを完了して接続まで確認するのにだいたい２日を要しました。
内訳としては以下のような感じです。（大体の所用時間感覚です。）

0. （ランニングコストなどの）調査　 -->  **2時間**
1.  DB のデプロイ —> **30分**
2.  フロントエンドのvercelへのデプロイ　--> **１５分**
3. バックエンドのECSを用いたデプロイ --> **２時間**
4.  お名前.comでドメインの取得 --> **30分**
5.  ACM、Route53、NLB、TargetGroupを用いたバックエンドのHTTPS化（TLSプロトコルの有効化） --> **4時間くらい？（ハマりました）**
6. データベースのバックアップ機構の作成　--> **1時間**
7. 全体の接続確認　--> **30分**

全体でだいたい
**１０〜１２時間くらい**
だった（気がします。）

## 想定されるランニングコスト

今回の構成だと、（だいたい）このくらいのランニングコスト（月額表示）になりそうです。

- データベース（RDS） (2000円）
- バックエンド（ECS）（1200円）
- フロントエンド（Vercel）（とりあえず無料）
- ロードバランサー等(2200円）
- その他（Route53, ドメイン）(100円）

**全体で5500円**
くらいでしょうか。

やはり個人開発でこのランニングコストはけっこうかかるなあと思ってしまいます。

**前回リリースしたモバイルアプリはFirebaseをバックエンド**で賄い、
**月額０円で運用している**
ため、ウェブアプリだとお金かかるなあと思ってしまいます。

仮にDBをもっと安価なサービスを使用し、
ロードバランサーを使用しない（ただHTTPでバックエンドを賄う、、？）
構成だと **半分くらいには抑えられそう**です。
この辺の、ランニングコストはサービスの継続にダイレクトに関わってくるところなので、
もう少し精査して可能そうならコスト削減を図ろうと記事を書きながら考えているところです。

**もしどなたかいい構成がありましたらぜひ教えてください、、。**

## 全体としての感想

#### Vercel は神サービスだと思う
Vercelは今までも個人ブログ

https://kenmaro.com

や、

前回リリースしたモバイルアプリ「YorimichiApp」のランディングページ、

https://yorimichiapp.com

などのデプロイでも使用していますが、React、Nextなどで作ったフロントエンドのコードのデプロイが非常に簡単にできるので、おすすめです。
簡単さ、手軽さでいうと控えめにいって神です。
大規模サービスにはもちろん向かないのかもしれません。
ただ、ここまでインテグレーションが簡単で、運用が楽なのは素晴らしいと思います。
GitHubにプッシュした段階でCIを走らせてデプロイしてくれます。

#### 結局AWSのRDSを使用した

今回のウェブサービスでは、
**PostgresqlをDBとし、NestJSのTypeORMを用いてデータ管理**
をしています。

DBのランニングコストが一番高くなるであろうことは理解しており、
調査段階でいろいろとサービスを調べました。Herokuを使うとDBは約半額の１０００円くらいで運用できそうでしたが、結局安心感をとってAWSのRDSを選択しました。
個人開発においてランニングコストを最小に抑えておくことは非常に大事だと思う一方、

- 今まで使ったことのあるAWSを使うことが一番学習コストも抑えれること
- 今後もこの構成を使いまわせること
- 口コミなどによる安定性や、速度など

を総合的に考え、今回はAWS上でDBを運用する構成にしてみました。
ただ上記の通りやはり
**ランニングコストは気になってはいます。。**

#### ドメイン取得はお名前.comがやはり最強？
今までいくつか作ってきたウェブサイトなど、私はお名前.comを使ってドメインを全て取得していたので、
そこを踏襲してなにも他を調べずにお名前.comを使用しました。
設定などもシンプルでわかりやすい気がしますし、今の所困っていることはありませんが、他のドメイン管理のサービスもあるのか少し調べてみたい気もしました。


## ハマった項目

デプロイを実行したときにハマってしまい、
思ったより時間を溶かしたところについてまとめておきます。

#### ACM, お名前.com, Route53, NLB  までの作りかた
何回やっても理解できていないし、時間がかかる。

基本的に
- ドメイン取得
- Route５３つくる
- ACM申請
- NS変更（Route53から） --> ここが時間かかるからここまであらかじめやっておくべき（半日くらいかかる）
- レコード（CNAME）追加
- ACMの申請が通る
- NLB(ALB)のターゲットグループをつくる
- NLBつくる（ACM、ターゲットグループが必要）
- Route５３にNLBを登録（Create record --> alias)
- ECR作る
- ECSタスク定義
- ECSサービス作る

みたいな手順


#### バックエンドのHTTPS化は必須？？

**バックエンドのHTTPS化に一番時間を要しました。**

理由は、やはりこのタスクにおいてどのような準備が必要なのか、自分の理解が浅かったことでした。

本来は、
**バックエンドはベータ版では普通にIPを公開し、**

**セキュリティグループでアクセスだけ絞る形で
TCPで普通に接続しようと考えていた**

ので、バックエンドのデプロイにはそこまで時間がかからないだろうと考えていました。
しかし、ECSでデプロイをした後にフロントから接続すると、以下のエラーメッセージが、、

```
Mixed Content: The page at 'https://www.protohub.tech/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://xxx.xxx.xxx.xxx:5101/posts'. This request has been blocked; the content must be served over HTTPS.
```

もしかするとHTTPS化を行わないでやりくりする回避策があったのかもしれませんが、
HTTPS化をするという方向で私は舵を切り、そのために必要なバックエンドサービスをAWS上で賄うことにしました。

その結果、**ACM、NLB、Route５３**
などのサービスを使う必要があることがわかり、いろいろと調べながら実装することになりました。

#### ロードバランサとECSタスクの紐つけ
**ここが一番ハマってしまいました。**

どこまでがTLSプロトコルでの接続であり、
どこからがTCPでの接続なのかの理解をなあなあにしたまま実装を進めてしまったことが原因でした。
結果として、フロントエンドからバックエンドに接続しようとした時に、

```
ERR_EMPTY_RESPONSE
```

というようなエラーとなっていました。

**Route53 --> NLB --> TargetGroup --> ECS**

の接続の流れをきちんと理解したところで実装の間違いに気づき、最終的には接続を確認することができました。

#### お名前.comにRoute５３からのNS（ネームサーバ）を設定、反映させるのには時間がかかる

お名前.comで取得したドメインをRoute53と連携する際に、NSの設定がお名前.comで必要なのですが、

**反映させるのに１２〜７２時間かかる、**

という記載がお名前.comにありました。

この点に注意し、他の作業を実行する前に前もってNSの設定をしておけばもっとスムーズだったのかなと思います。


## 役に立った記事など

ハマったとき、サービスのつながりについて理解が浅かったことを痛感しましたが、
いろいろな記事に救われました。
**このようにまとめてくださっている人がいることに感謝申し上げます。**

#### バックエンドHTTPS化の大まかな手順の記事（非常に助かりました。）
https://zenn.dev/shivashi/scraps/2fd1c744d0a860

#### ACM, Route53, お名前.com　（CNAMEとかの手順）
https://deep.tacoskingdom.com/blog/12


#### お名前.com、Route53の絡みの理解（控えめに言って神記事でした、非常に助かりました。）
https://blog.i-tale.jp/2020/04/13_02/#%E3%81%9D%E3%81%AE%E5%89%8D%E3%81%ABurl%E3%81%A8%E5%90%8D%E5%89%8D%E8%A7%A3%E6%B1%BA%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%A3%9C%E8%B6%B3%E3%81%97%E3%81%BE%E3%81%99



#### ACM の証明書を作りロードバランサーと接続するときのドキュメント

https://aws.amazon.com/jp/premiumsupport/knowledge-center/associate-acm-certificate-alb-nlb/



#### ELB(ALB, NLB, CLB)がそれぞれどう違うのかがよく説明されている。

https://ex-ture.com/blog/2021/07/14/elb-alb-nlb-clb/


#### postgresql のバックアップ（ほとんど使いまわせました、非常に助かりました。）
https://gist.github.com/valferon/4d6ebfa8a7f3d4e84085183609d10f14


## 終わりに

今回は個人開発のウェブアプリベータ版をデプロイするときの構成について、
備忘録的にまとめてみました。

やはりランニングコストが気になるところではあります。
もしかすると経験のあるひとからするととても効率の悪い構成にしてしまっているのかもしれないので、
どなたかアドバイス等ございましたら書いていただけますと嬉しいです。

運用や構成などについて今一度精査してみようと思っていますが、
今回はこのように備忘録としてまとめてみました。

今回はこの辺で。


@kenmaro