【個人開発】ラーメン待ち時間シェアアプリ「ちゃくどん」を作ってみました【Rails, Hotwire, AWS, Docker, GitHubActions】


## はじめに

「[ちゃくどん](https://tyakudon.com)」というWebアプリをリリースしましたので紹介させてください！
私は非エンジニアで子供が3人いることもあり、制作期間10ヶ月とコツコツ開発してきました。制作アプリの解説に加えて、開発・運用していく過程においての学びや、失敗談についてもシェアできたらと思います。

:::note warn
2024年3月22更新情報
現在は、利用状況などを踏まえ、Fly.ioで運用しています。
AWS関連の記述は、参考程度にしていただけたらと思います。
:::


## ちゃくどんとは？

ざっくり説明すると、ラーメン店に並びはじめる「接続」から、ラーメンが提供される「着丼」までの待ち時間である「ちゃくどんレコード」を共有するアプリです。

|ちゃくどんレコードの計測・登録|ちゃくどんレコードの閲覧|
|:-:|:-:|
|![measure.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/e6027e72-7c8a-5a88-594b-ad38306e4497.gif)|![レコード閲覧.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/ff5f1896-77aa-fe17-7ee6-3525f3e16aac.gif)|
|現在地付近のラーメン店に対して、行列の様子を入力した上で、ストップウォッチ形式でちゃくどんレコードを登録します|ちゃくどんレコードには、接続・着丼時刻のほか、時間経過で変化する行列の様子を確認することがきます|

:::note info
スマホ利用を想定しており、iOSのSafariとChrome、MacのSafariとChrome、WindowsのEdgeとChromeでの動作を確認しています。
:::

[GitHubリポジトリはこちら](https://github.com/moriw0/tyakudon)

## なぜちゃくどん？

ちゃくどんを開発した理由は、**Twitter上の待ち時間を共有するカルチャーに着目**したのがきっかけです。ツイートには、いつ、どれくらいの行列で、どのくらいの待ち時間で、といった情報が含まれます。

![着丼ツイート例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/76b4241b-796e-afd1-16ec-2a92c040aef5.png)

私自身、ラーメンを食べる前にはこれらの情報を確認した上で、来店に臨んでおりましたが、投稿される情報はバラバラだったり、そもそも情報がなかったりします。ある日、Twitterでの着丼情報が見つからないまま、人気ラーメン店に突撃したものの、予想以上に行列が進まず、敢えなく断念することがありました。**長時間の待ち時間を無駄にし、食べたかったラーメンを食べられなかった苦い経験**はもう二度とごめんです。これは、特に時間が限られている旅行中でもありがちな問題だと思います。

そこで、これらの情報を簡単に投稿できて、整理された状態で確認できるプラットフォームがあると、この**待ち時間を共有するカルチャーがもっと広く浸透して、来店計画が立てやすくなったり、ラーメンを断念するという問題も解消される**のでは？と考えました。

そして、待ち時間情報の集約によって店舗側にもメリットがあるはずだと妄想が膨らみます。待ち時間はラーメン提供時間の指標ともなるため、回転率向上のきっかけや、来店時間の分散といった、**ユーザーと店舗の双方がWin-Winとなり得る**のでは・・・？と。そして、調べてみると競合もいなそう。これまで夢にみていた、世の中にないプロダクトを作ることができるとワクワクしながら、これまで作っていた別プロダクトを投げ出し、新たにスタートさせました。

## ちゃくどんの機能・特徴 10選

ちゃくどんの機能や特徴について、もう少し詳細にご紹介します。機能はUI・UXを意識しつつ、実際に私が使う中で便利だなと思ったもののほか、フィードバックを元に充実させていきました。

### 1. ちゃくどんレコードのランキング表示

トップページではランキングを表示しており、項目として、遅い着丼（待ち時間が長い）、速い着丼、いいね数があります。私は人気ラーメン店で長く並ぶことも基本的には苦ではなく、むしろ誇らしくなるし、3時間並んでいる人をみると感心します笑　そこで、完全に主観になりますが、**遅い着丼は名誉あるランキング**として扱い、最初に表示しています。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/67d94a40-35ef-f1af-0382-06c7bd48aad4.gif">

### 2. Twitterへの共有

Web Intentにより、ちゃくどんレコードページ内のシェアボタンを押すと、次の情報を自動で入力した状態でツイート編集画面に飛びます。これまでより、楽にツイート文を作成できることが目的ですが、入力フォーマットはまだ悩んでおります。
- 店舗名
- 待ち時間
- ちゃくどんレコードである、`/records/:id`へのURL

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/120f000f-3ee3-640d-f942-6ec202e3448b.gif">

### 3. 店舗マップ表示

店舗ページではマップを表示するほか、Maps URLを使用した店舗までの経路も、ボタン１つで確認することができます。ちゃくどんレコードを登録していると、次第に新たなラーメン店に挑戦したくなってきます。そんな時に、経路を簡単に確認できると便利だと思い、実装しました。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/d6069105-6b05-f6a2-8f49-71570952154f.gif">

### 4. ログイン機能

上述の機能はログイン不要ですが、ちゃくどんレコードの登録や、次から紹介する機能はログインを必要とします。メールアドレスとパスワードによる通常ログインと、Googleログインを取り入れており、通常ログインは認証周りの知識を深めたいと思い、Gemなしで実装。**通常ログインとGoogleログインの共通処理は、concernsを利用してまとめる**といった、保守性を保つ工夫をしています。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/2ef626fd-08e8-0d23-9318-3d3ebbaf4da8.png">

### 5. 待ちユーザーへの応援メッセージ機能

待ち時間中のユーザーに対して、定期的に応援メッセージを出力する、プチサプライズ機能です。待ち時間は通常ネガティブに感じるものですが、そんな時間にクスッと笑えて、むしろ楽しみできるような仕掛けを作りたいと思い実装しました。また、応援メッセージは、**参考情報として重要な行列の様子に反応して自動生成**されますので、行列の様子を投稿してもらう動機付けの狙いもあります。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/3cec5838-2ae6-afcc-87a3-ec3bb6659550.gif">

### 6. ちゃくどんレコードへのいいね機能

こちらはベータテスト期間中のユーザーフィードバックで実現したものです。ちゃくどんレコードへの信頼性向上のほか、投稿ユーザーへのモチベーションアップを目的に実装しています。**ついつい押したくなるようなインタラクションを付与している**のもポイントです。
    
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/1bab500f-fc0d-fdac-ecb4-5d0f9fd562f7.gif">

### 7. 店舗お気に入り機能

よく訪れたり、気になるラーメン店をお気に入り登録することで、お気に入り店舗のみのちゃくどんフィードや、お気に入り店舗ごとの最新ちゃくどんレコードを確認することができます。お気に入り店舗が増えた際に、店舗を絞り込んでちゃくどんフィードをチェックする、なんて使い方もできます。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/fbb272f1-c5c6-89fc-f685-e135260d7ffd.gif">

### 8. ラーメン店舗情報のスクレイピング 

全国の約1万7千店舗ラーメン店舗情報はスクレイピングによって取得しています。スクレイピングは**Thorタスクとして定義し、ECS Scheduled Taskにて定期実行**しました。Thorタスクは、可読性を保つようservicesに処理を切り出したり、スクレイピング対象サイトに負荷をかけないよう、夜間に1ページあたり30秒の間隔をあけて取得するといった考慮をしております。スプレッドシートに店舗情報を記載している理由として、将来的に使用する情報を格納したり、将来的にスプレッドシート上の店舗情報を変更してアプリに反映させるといった連携を検討しているためです。

|　関連ダイアグラム　| Thorタスクフローチャート |
|:-:|:-:|
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/8a8708e7-829a-eec7-45d8-da033b70bf4b.png">|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/8103db5e-2736-46e6-2f3a-a31a36b05a5e.png)|


### 9. 店舗登録リクエスト機能

上記のスクレイピングによって人気店は網羅的に登録していますが、登録のない店舗に対して「自分でも店舗が登録したい」というフィードバックを受けて実現したものです。フロー図の通り、ユーザーから店舗名と店舗住所添えてリクエストを出すと、管理者はフォームに自動入力された店舗情報を精査して登録することができます。これは不正情報での店舗登録を防ぐほか、元々実装していた店舗登録処理を生かし、バリデーションなどの手続きを統一するため、このような処理にしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/0e913237-e11c-5670-845a-6c861da4765e.png)


### 10. Youtubeによる解説動画

開発背景から、利用方法、今後の展望などを紹介するビデオをゆっくり形式で制作しLPに掲載しております。制作背景としては、ベータテスト期間中に「利用方法がわかりづらい」という意見を多数頂いたことがきっかけです。直感的なUIにこだわり制作しておりますが、確かに前提条件などが揃わないと分かりづらい側面があり、**霊夢と魔理沙の問答によって面白おかしく分かりやすく伝える**という観点でゆっくり動画はピッタリでした。

https://www.youtube.com/watch?v=HobXb57a8OI&t=5s

## 使用技術と選定理由

ちゃくどん開発の技術選定プロセスには、[実務ができるエンジニアスクール](https://www.youtube.com/watch?v=VlSA0R_zebs)での**2ヶ月間の業務委託経験が大きく影響**しています。前述で紹介したThorタスク化や、GoogleSpreadSheetとの連携などの知見が代表的な例で、この経験に関する詳細は[こちらの記事](https://qiita.com/moriw0/items/445a2b39e1c56522a71f)で共有しています。

:::note info
実務ができるエンジニアスクールは、新たに[APPRENTICE](https://apprentice.jp/)というサービスに進化して運営されております！
:::

### フロントエンド

**HTML (erb)**
簡潔に表現できるSlimテンプレートエンジンも魅力的ですが、世の中のerbで説明されている情報をSlimに変換するのに、逆にコストがかかると思い、erbを採用しています。

**Sass**
CSSの拡張機能を用いて、より効率的かつ管理しやすいスタイリングを実現しています。

**Bootstrap 5**
開発初期段階で簡単に操作可能な見た目を実現するため、一部のコンポーネントやユーティリティで使用し、随時独自のCSS(Sass)に置き換えています。

**Hotwire (Turbo, Stimulus)**
JavaScriptフレームワークは現代のWeb開発では欠かせない要素ですが、Hotwireを採用したのは、**最小限の学習コストで擬似SPA（シングルページアプリケーション）を実現**できる点に魅力を感じたためです。将来的にアプリの規模が拡大した場合、Reactへの移行も視野に入れています。

### バックエンド

**Ruby 3.2.2**
Rubyの学習を始めた理由ですが、豊富なドキュメントが存在するほか、Rubyの直感的な記法に魅力を感じました。また、**Rubyを習得すれば他の言語へも移行可能なはず**だと考えました。

**Ruby on Rails 7.0.4.3**
MVCフレームワークを用いて迅速なWebアプリケーションの開発を実現しています。

**PostgreSQL 14.6**
初期のホスト先であるRenderが、PostgreSQLをサポートしていたこと、そして、ActionJobのキューイングバックエンドとして、PostgreSQLを使用できるGoodJobが、低コストで運用可能だったためです。

### インフラ

**AWS**
AWSを採用したのは、後述するRenderでの課題から、より高度な可用性とスケーラビリティが求められたからです。EC2, ECS, CloudFrontなどのサービスを組み合わせることで、課題解決をすることができました。

### CI/CDツール

**GitHub Actions**
CircleCIと比較した結果、GitHub Actionsを採用しました。その決め手となったのは、多くのアクションを使用することによって、様々な自動化を可読性を保って実装できる点と、幅広いトリガーに対応できる柔軟性です。

### 開発環境とその他のツール

**Docker / Docker Compose**
開発環境の迅速なセットアップを可能にしています。

**RSpec**
実装したコードが正しく動作するか保証するため、テストを導入しています。Mintestと比較し、その表現力の高さと機能性から採用しました。

**RuboCop**
RuboCopを用いて、コードスタイルと品質の維持に努めています。

### 使用した代表的なGem

**geocoder**
住所を元に、経度・緯度情報を取得するために使用しています。また、`RamenShop.near(緯度, 緯度, 半径)`のような、直感的な書き方で現在地周辺のラーメン店を取得することができます。

**ruby-openai**
チャットする感覚で、簡単にOpenAI APIとのやりとりを実現できるライブラリです。応援メッセージ生成に使用しました。

**google_drive**
Googleスプレッドシートとの連携に利用しました。`google-api-ruby-client`という公式ライブラリもありますが、こちらの方がより簡素に利用できるため、好んで利用しています。

## ちゃくどんアーキテクチャ
ちゃくどんのインフラは、高可用性とスケーラビリティを目的として、AWSを中心に構築しています。

### インフラ構成図
AWSサービスの構成に加えて、CI/CDパイプラインや使用サービスとの連携について、次の図で示します。

![tyakudon_icd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/e01b1def-f06f-6f2e-3d0a-8c1bc5f6c4d2.png)

### AWSについて

各サービスの役割や選定理由を解説します。

**EC2**
最初は、PostgreSQLをRDSで運用しておりましたが、コスト削減のためEC2にPostGreSQLをインストールして、データ管理を行っています。

**ECS(Fargate)**
Dockerのメリットを最大限生かすため、コンテナ管理サービスであるECSを採用しました。これにより、デプロイの迅速性とスケーラビリティ、運用の効率性を向上させています。

**ALB**
https通信の復号のほか、障害時やオートスケール時の入力トラフィックを適切なコンテナに分散させています。

**CloudFront**
コンテンツ配信ネットワーク (CDN) を利用して、静的ファイル（CSS、JavaScript、画像ファイル）の高速配信の他、**AWS ShieldによるDDoS保護**を担っています。

**CloudWatch**
アプリケーションとインフラのモニタリングを行い、ログの集約やアラートの設定をしています。

**SNS, ChatBot**
システム異常や重要な通知をSlackに発信しています。

**Route53**
お名前.comで取得したドメインを、CloudFrontにルーティングさせる他、メール送信で使用するサブドメインの管理を行なっています。

**Certificate Manager**
Cloud FrontとALBに設置するSSL/TLS証明書を管理しています。

**IAM**
AWSリソースへのアクセスを安全に管理し、ユーザーやサービスの権限を細かくコントロールしています。

**S3**
アップロード写真を低料金で永続化するために使用しています。

### CI/CDパイプラインについて

GitHubActionsを用いて次の自動化を実現しています。

**CI**
プルリクエストをトリガーとして、RSpecによるテストとRuboCopによるコード解析を実行します。

**CD**
メインブランチへのマージをトリガーとして、次のフローでECRへデプロイします。
1. Dockerイメージのビルド
1. コミットハッシュを用いたイメージのタグづけ
1. イメージをECRにプッシュ
1. プッシュしたイメージを使用するために、タスク定義を更新
1. タスク定義を元にサービスの更新
1. サービス更新結果をSlackに通知

## ちゃくどんER図

主要なテーブルとその関係性についての概要を記述します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/a6278f79-be3a-ec7c-da3a-aea89b269b76.png)


※Active StorageやGem導入で生成されるテーブルは除いて記載しています。

### 各テーブルの役割

| テーブル名 | 役割 |
| --- | --- |
| Users | アプリのユーザー情報を格納。ユーザー名、メールアドレス、パスワード（ハッシュ化済み）などの基本情報が含まれます |
| RamenShops | ラーメン店の情報を管理。店名、住所、ジオコーディング情報などが含まれます。 |
| Records | ユーザーによって記録されたちゃくどんレコードを格納。接続時刻と着丼時刻、待ち時間が記録されます。 |
| LineStatuses | ラーメン店の行列の状態を示す情報を管理。店外か店内か、着席かなどの状態が含まれます。 |
| CheerMessages | ユーザーに送信される応援メッセージの内容を格納。メッセージ内容とその条件が記録されます。 |
| Favorites | ユーザーがお気に入りに登録したラーメン店の情報を管理します。 |
| Likes | ユーザーがレコードに対して付けた「いいね」を管理。どのユーザーがどのレコードにいいねをしたかが記録されます。 |
| ShopRegisterRequests | ユーザーからの新しいラーメン店の登録リクエストを管理。店名、住所、ユーザー情報が含まれます。 |

## ちゃくどん開発プロセス

機能単位で要件定義し、設計・実装する開発プロセスをとっています。基本的には次の流れで実施していきますが、各フェーズを行き来することも多くあり、紙に書き出したり、Notionなどの各種ツールも交えてアイデアを整理し、詳細を詰めていきました。

### 要件定義

まず、現状の課題からありたい姿をもとに、実現したい機能を抽出していきます。機能実現は技術的に可能なのかWebで調査するほか、実際に手を動かして確認し、要件を確定させます。

### 画面設計

Figmaを活用して実現したいアプリのデザインを視覚化し、画面遷移図を作成しました。このプロセスでは、見た目だけでなく、**各画面で何ができるのか**という設計フェーズで必要となる情報の抽出に重点を置きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/8fccdce9-3a09-b601-5366-7ec46ac85549.png)

[Figmaページ](https://www.figma.com/file/EtH7c4aLMlywiolp9TLghI/%E3%81%A1%E3%82%83%E3%81%8F%E3%81%A9%E3%82%93%E7%94%BB%E9%9D%A2%E9%81%B7%E7%A7%BB%E5%9B%B3_%E5%85%AC%E9%96%8B%E7%94%A8?type=design&node-id=0%3A1&mode=design&t=wiYJ0M0OR2juTqnn-1
)


### 機能・DB設計

画面設計を基にして、システムの裏側で実行される処理とそれに必要なデータを抽出します。画面とデータベース間で交換されるデータの流れと内容を理解することで、テーブル設計をスムーズに行えるようになります。最終的にテーブル間の関係をER図で整理します。

### 実装

ここまでの設計で作りたいものを明確にすることでプログラミングは比較的楽になります。実装にあたっては**実際の開発プロジェクトを想定**し、GitHubのIssuesによる問題の共有や、わかりやすいプルリクエストによる変更管理を行なっております。

<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/adf89494-d17f-76ba-7789-1364324d599e.gif">


## ちゃくどん開発の裏側

ちゃくどん制作期間は、構想や試作、途中の技術キャッチアップ含めて約10ヶ月、時間にして約650時間です。予備知識なしの場合、**１つのプロダクトを作るのに1000時間以上**の時間が必要になっていると思います。開発を継続する上で日々の習慣や環境を整えることにより、生産性が上がることを実感しました。色々試した上で私が合っていた事例について紹介します。

### 作業時間の確保と生活習慣の見直し

働き、子育てしながらでの時間の確保が一番の課題で、家族の理解を得ながら継続するために、無理な時間投下は避けるようにしました。早朝時間に1h、通勤途中の電車内で往復2hの計3hの作業時間を確保し、そのほかの隙間時間をインプットする時間に充てました。また、以前は夜型で睡眠の質が悪く、常に眠気と闘っておりましたが、朝型に切り替えてからは、パフォーマンス高く保ちタスクをこなすことができるようになりました。

### 学習記録をとる

Study Plusというアプリを使ってプログラミング学習・作業記録をつけておりました。これには、記事作成やワイヤーフレーム制作などの時間も含まれますが、時々見返してモチベーションを保つ他、**実績を踏まえた作業時間の見積もり**にも役に立ちました。

<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/1b247d7f-4ddc-971a-1624-523fbc31a65c.png" alt="image.png">

### GTD手法によるタスク管理

GTD(Get Things Done)手法をNotion上で実践し、開発だけでなく私生活タスクも管理しています。**頭の中の考えを全てはき出し、適度に優先順位をつけ**ることで、あとは淡々とタスクをこなすことができるようになります。また、ポモドーロテクニックによって定期的にリフレッシュすることで、生産性を保つことができたと思います。

https://www.youtube.com/watch?v=G82JLeUs4NM&t=2198s

### メモ魔になる

インプットした内容を定着させるめに、アウトプットとして記事作成までできれば、ベストだと思いますが、**メモレベルでも十分効果がありました**。インプットの定着のほか、開発中に考えたことや試したこと、結果などを全てNotionにメモしております。これによって同じミスを繰り返すことを防いだり、誰かに質問する際は状況を共有して分かりやすい質問することができるようになります。そして、アプリが完成したら紹介記事を書きたいと開発初期から考えていたため、それも見据えてメモしていたのも効果的でした。

### デスク環境を改善

最初はMacbook１つで作業しておりましたが、快適に作業できるよう、少しずつ環境をアップグレードしていきました。特に、２画面化により教材が見やすくなることで、学習効率が上がったり、キーボードの変更によって、タイピングの時間が心地良くなり、**デスクに向かう時間がより楽しく**なりました。

<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/7d56493e-6508-8815-d198-2577cda3aa72.jpeg" alt="IMG_5042 copy.jpg">

### メンターシップでレベルアップ

後半の制作期間では、経験豊富なプロのエンジニアにメンターとして伴走していただきました。設計のアドバイスやコードレビュー受けることにより、**実務に近い知識やスキルのほか、質問力の向上**も図れたと思います。また、将来のキャリアについての相談や激励いただいたりと、開発を続けていく上で大変励みになりました。お世話になった[sugaさん](https://menta.work/index.php/user/62016)は、気さくで大変おすすめできるメンターさんです！


## ちゃくどん制作で苦労したこと

ちゃくどん制作では最初から最後まで苦労しましたが、中でも印象に残っているエピソードを紹介します。

### 応援メッセージ機能の開発

サプライズ機能である応援メッセージ機能の開発は、OpenAI APIとの連携に加え、Active JobやActive Cableなどの複数の技術要素を組み合わせて実現しております。実現にするにあたっては、**バックエンドの複雑性に加え、非同期処理やブラウザ仕様の把握などのフロントエンド技術も求められ**、それぞれの要件定義から実装に至るまで、多くの困難に直面しました。ChatGPTと壁打ちしながら設計と実装に取り組んだものの、新たなバグの発見や要件の見落としが度々あり、安定して機能するようになるまでに時間がかかりました。苦労した分思い入れのある機能になります。

### UIがダサくなる

フロントを実装すると、基本デザインがダサくなってしまいます。デザイナーではないので仕方ないかもしれませんが、ユーザーからしてみれば、ダサいデザインのアプリは使いたくないものだと思います。この分野においては、ChatGPTに相談しても、なかなかいい答えが返ってきません笑　書籍で簡単にデザインを勉強し、参考となるデザインを研究しつつ、Figmaでのデザイン起こしと実装を繰り返し、家族のフィードバックを得ながら改善を重ね、最終的にはユーザーが快適に利用できるUIを実現できたと思います。

### AWSへのデプロイとインフラ構築

AWSへのデプロイは、プログラミングスキルだけでは乗り越えられない、**ネットワークやシステム管理に関する深い知識が必要とされます**。多くのエラーとその対処法を学びながら、インフラ周りの知識を習得し、目標のアーキテクチャを構築することができました。次のセクションでも詳しく紹介しますが、この過程で実践的なスキルも身につけることができたと思っています。

## ちゃくどん運用における改善点と学び

実際にアプリを運用してみることで、アプリケーションバグの発見のほか、特にインフラ面で多くの課題が明らかになりました。以下では、運用開始から一般公開に至るまでの、主な改善点と学びを紹介します。

### Renderでベータテスト開始

メイン機能が一定の完成度に達した段階で、Renderのフリープランにホストしてベータテストを行いました。シンガポールリージョンを使用しておりましたが、**ページ遷移に3秒近く要したり、GETリクエストでもサービスがダウン**するなどの、パフォーマンス問題がありました。また、30分の未使用で自動的にスリープに入る仕様もあり、Standardプランに変更するも、写真アップロード後の、画像処理によるメモリ不足問題も露呈し、Renderからの移行を決意しました。

### RenderからAWSへの移行

画像リサイズ処理での、メモリ不足によるサービスダウンを解決するために、AWSの東京リージョンにある、EC2とRDSへの移行を実施。これにより処理速度が大幅に向上しましたが、次の問題は残ったままでした。

- **環境差異**：開発環境と本番環境の差異により、たびたびデプロイ中やデプロイ後にエラー顕在し、調査や対応に時間を要していました
- **デプロイ作業が煩雑**：デプロイ自体はできたものの、今後の頻繁なアップデートのたびに、煩雑な手順を繰り返すことを考えると耐え難いものでした
- **セキュリティアタック**：パブリックIPを解放していたため、`/.env`へのアクセスなどシークレット盗聴を試みるような攻撃を受けていました
    
### ECSへの移行とCI/CDの導入

前述の問題に加え、スクレイピングタスクのスケジュール実行などのニーズに応えるため、ECS Fargateへの移行と、CI/CDパイプラインの構築を行いました。これにより、デプロイプロセスの高速化とインフラの安定化を実現しました。機能アップグレードの、プルリクエストをマージするたびに即本番へ反映されるので、**自動化して本当によかった**と実感しています。

### コスト最適化での失敗

円安の影響により、AWS運用コストが課題でした。特に、RDSは低スペックのt3.microであっても、約$30／月とサービス継続の重荷になっていたため、RDSからEC2へデータベース移行し、一般公開を開始しました。今では悔やんでも悔やみきれませんが、移行先のEC2にスポットインスタンスを使用してしまい、**データ消失という重大なインシデント**を発生させてしまいました。詳細については次の記事に記載しています。この反省から、構成と設定を見直し、現在のインフラ構成となっております。

https://zenn.dev/moriw0/articles/24063e53b79190

### ユーザー獲得への挑戦

一般公開後のユーザー獲得は、予想以上に難航し、**マーケティングの難しさ**を痛感しています。公開まで頑張ってきた分、思った以上に流行らない現実は、本当に辛いです。ここでの教訓は、シーズ志向だけでなく、**初期段階から、ユーザーニーズを把握した上で設計していくことが重要**だったと考えています。とはいえ、宣伝活動を通じて、徐々にアプリの認知度を高めていく方針で、発信を続けています。

### 今後へ生かすために

この運用経験は、適切なインフラ選定やセキュリティ対策、コスト管理、そしてユーザー獲得戦略などの重要性を学びました。今後は、初期段階からこれらの要素を考慮に入れ、より効果的な開発と運用を展開していきたいと思います。

## ちゃくどんの課題

ちゃくどんはまだまだ進化の途中です。ユーザーからのフィードバックを受けながら、より使いやすく、より楽しいアプリへと成長させていきたいと考えています。そのほか、次の課題について今後挑戦していきます。

### インフラの更なる見直し
お小遣い制の筆者にとって、AWSでアプリを公開し続けることを考えると、体力に自信がありません笑　2024年2月になった今、**IPv4の有償化もお財布に大打撃**です。選択肢はまだ色々とありそうなので、パフォーマンスと料金を両立するインフラ構成を、今後模索していきたいと思います。ちなみに、現在の維持費は約$45.9／月で、内訳は次のとおりです。

<table>
  <caption>月(750h時間)あたりの費用内訳</caption>
  <thead>
    <tr>
      <th>サービス</th> <th>料金($)</th>
    </tr>
  </thead>
  <tr>
    <td> ALB </td> <td>18.2</td>
  </tr>
  <tr>
    <td> PublicIP (ALB: 2個, ECS: 1個) </td> <td>11.3</td>
  </tr>
  <tr>
    <td> EC2 (t2.micro) </td> <td>11.4</td>
  </tr>
  <tr>
    <td> ECS (0.25 vCPU, 1 GB, スポット) </td> <td>4.5</td>
  </tr>
  <tr>
    <td> Route 53 </td> <td>0.5</td>
  </tr>
</table>	

### 公正なデータの取得方法

ラーメン待ち時間の公正なデータ取得は、開発初期からの大きな課題です。ラーメン店への接続操作は現在地情報に基づき制御しておりますが、同様に着丼操作時にも現在地情報を取得して、店舗付近でなければ注意を促すラベルを表示する、などの対策を検討しています。

### 着丼操作忘れへの対策

ラーメン提供後に着丼操作を忘れるケースへの対応として、一定範囲の時間内であれば、時間調整を可能にする、などの救済措置が必要だと考えています。また、アクティブな行動を定期的に促す通知機能の導入を検討しています。後者の機能を実装するため、ネイティブアプリ化も視野に入れています。

## 学習教材の紹介

これまで学習してきた教材の中で、特に良かったものをご紹介します。ChatGPTなどのAIにより、やりたいことを簡単に実装できる時代になりましたが、**生成されるコードが採用できるか判断できるようなるため**にも、基礎学習が必要だと考えています。学ぶ内容はどうしても広範囲になりますが、最初は頭の中にしおりを作る感覚で読み進め、必要になったら読み返し、手を動かしながら学ぶというスタイルが効果的でした。

### バックエンド編
Ruby on Railsやその周辺知識についての教材を紹介します。

**プロを目指す人のためのRuby入門**

Rubyの土台を固めるのにお勧めです。Ruby on Railsを学習する上で出てくるブロック記法など、書いていてよく分からないけど動いているみたいな状況を、Rubyの基礎を学ぶことで解消されました。

[プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)](http://www.amazon.co.jp/dp/4774193976)

--- 

**Railsチュートリアル**

Twitterライクなアプリを作ることで、一連のWebサービス作りを学びます。Webサービスってこのようにできているんだ！と、作りながらワクワクしていたことを思い出します。基礎知識に乏しくても完走できるよう設計されていますが、難度も高く、私は解説動画も購入して理解を深めていきました。

https://railstutorial.jp/

--- 

**パーフェクト Ruby on Rails**

Railsの各機能やお作法を、ミニアプリを作りながら掘り下げて学ぶことができます。ちゃくどん開発においても、実践的なエッセンスを取り入れることができたと思います。

[パーフェクト Ruby on Rails 【増補改訂版】 (Perfect series)](http://www.amazon.co.jp/dp/4297114623)

--- 

**Everyday Rails - RSpecによるRailsテスト入門**

RSpecの入門にお勧めです。Minitestから入ったため、RSpecの記法には最初戸惑いがあったのですが、こちらで理解を進めた今では、RSpecは非常に親しみやいテストフレームワークとなりました。

[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp)

--- 

**RSpec スタイルガイド**

RSpecの可読性を、さらに向上させる上で参考になりました。記事などを見ていると、RSpecの記法は人によって様々ですが、こちらのガイドに乗っとることで、一定の可読性を保つことができます。

https://github.com/willnet/rspec-style-guide

--- 


**達人に学ぶDB設計徹底指南書**

タイトルで上級者向けかと尻込みしていましたが、非常に読みやすい一冊でした。実装が楽になるDB設計となるよう、アプリ制作前に読んでおきたいです。

[達人に学ぶDB設計徹底指南書: 初級者で終わりたくないあなたへ](http://www.amazon.co.jp/dp/4798124702)

---

### フロントエンド編
私は初期段階でフロントエンドの学習をスキップしてしまったのですが、体験の良いサービスを作るためにも、Railsを学ぶ前か並行して押さえておくことをお勧めします。

**1冊ですべて身につくHTML & CSSとWebデザイン入門講座**

HTML, CSS基礎を学ぶのは、これ一冊で十分でした。最終的に出力されるHTML構造を意識してバックエンドを操作できるようになると、サービス作りが捗りました。

[1冊ですべて身につくHTML & CSSとWebデザイン入門講座](http://www.amazon.co.jp/dp/4797398892)

---

**JavaScript本格入門**

奥深いJavaScriptの基礎を学ぶのにお勧めです。今回は使っておりませんが、ReactやVueを学ぶ前にも押さえておくと良いと思いました。

[改訂3版JavaScript本格入門 ～モダンスタイルによる基礎から現場での応用まで](http://www.amazon.co.jp/dp/4297132885)

--- 

**猫でもわかるHotwire入門**

擬似SPA仕様のアプリ作りを通して、無料でHotwire(Turo, Stimulus)について学ぶことができます。Hotwireは学習コストが低い一方で、リッチな見た目を作ることができるため、コスパが良く大好きになりました。

https://zenn.dev/shita1112/books/cat-hotwire-turbo

:::note info
もし教材の初期段階でつまづく場面がありましたら、私の解説記事も参考にしてみてください！
:::

https://qiita.com/moriw0/items/2a3fe3ae2ead77d05ba7

--- 

### インフラ編

AWSを理解してインフラを組めるようになるには、ネットワークなどの周辺知識も必要となり、時間を要しました。様々な教材を通して、共通の観点やエッセンスとなる箇所を発見できて、学びが深まりました。

#### AWS基礎編

基礎編での学習を通じて、AWSへの自動デプロイができるようになります。

**Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書**

AWSの主要サービスの概要を把握するのに、サラッと読める一冊です。AWSのサービスは広大なので、これを読んでおくと各サービスの学習や作業をする際、迷子になりにくいと思います。

[図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書](http://www.amazon.co.jp/dp/4297108895)

--- 

**ゼロから実践するAmazon Web Services**

解説が丁寧なので、その名の通りゼロから実践しても理解できます。WordPressアプリのデプロイを通じて、EC2, RDS, CloudFrontといった技術を活用して、インフラを構築できるようになります。

https://www.udemy.com/course/aws-and-infra/

--- 

**RailsアプリケーションをAWSに自動デプロイする方法を学ぼう！**

EC2に対してGitHubActionsを用いた自動デプロイを学びます。NginxやCapistranoといった技術との連携も学べます。適宜参照ドキュメントを紹介してくれるので、最新の情報にもアクセスしやすいです。

https://www.techpit.jp/courses/200

:::note info
登場する技術が多いため、私は迷子になることが多かったです。用語を整理した上で図解する記事を書いていますので良かったら参考にしてみてください
:::

https://qiita.com/moriw0/items/38b5ee4348087df92682

--- 

#### AWS発展編
ECSへのデプロイができるように複数の教材で学びました。デプロイするアプリはRailsではありませんが、作業の本質的なところは変わらないので参考になると思います。

**AWSでDockerを本番運用！AmazonECSを使って低コストでコンテナを運用する実践コース**

バックエンドはLaravelで、低コスト構成なECSへのデプロイを学びます。解説は丁寧で、M1 Macで陥りやすいDockerイメージのビルド対策についても解説があります。

https://www.udemy.com/course/ecsfargate/

--- 

**Amazon ECS × GitHub Actionsで始めるコンテナベースのアプリケーション開発**

GitHubActionsにより、NodeJSアプリをECSに自動デプロイする方法を学ぶことができます。その他、VPCエンドポイントの利用やSlackとの連携など、高度な内容も盛り込まれています。

https://www.udemy.com/course/ecs-githubactions/

--- 

**docker基礎からのコンテナ構築**

Dockerのメリットから始まり、コンテナの操作方法や、ネットワークを利用したコンテナの連携を学ぶことができます。上記の２種の教材でもDockerの簡単な解説がありますが、一冊を通して体系的に学ぶことで導入がスムーズになると思います。

[さわって学ぶクラウドインフラ docker基礎からのコンテナ構築](http://www.amazon.co.jp/dp/4296106422)

--- 

### その他のお気に入り教材

その他のお気に入り教材を一挙にご紹介します。

**もう怖くないGit！チーム開発で必要なGitを完全マスター**

コード管理で必須なGitですが、基本CUI操作のためなかなかイメージすることが難しいと思います。手を動かしながらイメージで理解するのに良い教材でした。

https://www.udemy.com/course/unscared_git/

--- 

**リーダブルコード**

良いコードというのは読みやすいコードだと思います。１年後の自分がわかるコードを書くことができるよう、定期的に読み返したい本です。

[リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)](http://www.amazon.co.jp/dp/4873115655)

--- 

**プロになるためのWeb技術入門**

Webサービスというのは様々な技術が組み合わさっているものです。この一冊でWeb技術の歴史を含めて学ぶことで、それぞれの技術が線になって繋がる感覚を得られました。

[「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか](http://www.amazon.co.jp/dp/4774142352)

--- 

**縁の下のUIデザイン**

デザインはセンスによるところも大きいと思いますが、少し学ぶだけでも多少マシになるものだと実感しました。一般化されているUIデザインが、なぜそうなっているのかも理解できる一冊です。

[縁の下のUIデザイン──小さな工夫で大きな効果をもたらす実践TIPS＆テクニック (WEB+DB PRESS plus)](http://www.amazon.co.jp/dp/4297134098)


## お世話になったツールやサービス

ちゃくどん開発・運用でお世話になったツールとサービスを紹介します。

### ChatGPT

ChatGPTは、開発プロセスにおいて欠かせないツールとなりました。様々な利用方法があると思いますが、主に次の点で利用しました。

**GPT-4**
- 技術用語をわかりやすく説明
- テストコードのテンプレート作成
- 要件定義や設計の検討
- 変数名や関数名の提案
- エラー解決のサポート

**DALL·E 3**

オリジナルキャラクターや、ユニークなエラー画面の画像生成に利用しました。他の画像生成サービスと比較しても、DALL·E 3のクオリティが特に高いと感じております。次のような適当な手書き写真も、いい感じに変身しちゃいます。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1754248/3ab51317-658a-c0db-f986-70425e927119.png">

```
# プロンプト例

添付画像をもとにイラスト化して
・どんぶりから手と足がそれぞれ2本ずつ生えている
・手足は小麦色でちょびっと筋肉質にする。
・足は素足で短めにする
・右手を使って箸で麺を持ち上げる
・左腕は下げておく
・ボールドで強調されたアニメ風
・麺の上に卵・なると・のりなどのシンプルな具材を盛る
・どんぶりから湯気を出す
```

### Canva

FaviconやOGP、YouTubeサムネイル作成に利用しました。豊富なテンプレートと使いやすいUIで、簡単に作成することができます。

### Cursor

VS Codeをベースに、ChatGPTが組み込まれたコードエディタです。テキストをコードに変換したり、プロジェクト全体のコードを参照するエラー解決に助けられました。

### ゆっくりMovieMaker4

ゆっくり形式でのアプリ紹介動画や、Twitter宣伝用の動画を作成するのに使用しました。開発と同じくらい、動画制作に熱中してしまうことにご注意ください笑

## 最後に

いかがでしたでしょうか。ちゃくどんの概要とその開発過程についてお伝えできたなら幸いです。

長期間にわたる開発の末、**身内以外の方からの新規ユーザー登録や、初めてのちゃくどんレコードが登録された際の喜びと感動**は、言葉では表せないほどでした。

技術を駆使して課題を解決する第一歩を踏み出せたこと、そしてこれからも学びを続け、さらにアプリをアップデートしていくことを楽しみにしています。

最後までお読みいただき、本当にありがとうございました！ラーメンを食べに行かれる際は、ぜひちゃくどんレコードを登録してみてください。皆様からのフィードバックを心よりお待ちしております！

https://tyakudon.com/lp

また、Twitterも更新中ですので、フォローいただけると嬉しいです。

https://twitter.com/tonka2w0