ストレスからの脱却
とんでもない嫌がらせにより、東京で平穏な暮らしをすることができなくなり、大好きだった東京を去って、泣く泣く地元福島県いわき市に帰ってきたおっさんです。
嫌がらせがなければ、今も東京に住んでいたことでしょう。
失った時間は二度と元には戻りません。私は自分が歩もうとしていた人生を壊されました。
誰に責任をとって貰えばいいのでしょうか?
地元に帰ってきても、嫌がらせは収まらず今も継続しています。
嫌がらせを現在進行形で体験している者として一つだけ断言させていただくと、巨大な宗教ネットワークを使った嫌がらせは実際にあります。
何の説明もないまま、嫌がらせが始まり、他人の人生を奪い、ストレスを与え続ける。
ストレス過多で病気になったところで、おそらく何も保証をすることはなく、知らんぷり。
所詮は、卑怯な奴らです。
この場所で被害の詳細を語るのは控えますので、単なる被害妄想的なおっさんとでも見ていただければ幸いです。
現在は、地元系親戚系企業のシステム部で、マクロやら、ルーターの設定やら雑用ばかりしております。
意図的に孤立するように仕向けられた嫌がらせの中で、孤独な環境を逆手にとって、
何か楽しいことをしようと思い立ち、プロダクト制作に取り組み出したのが始まりです。
この記事につきましては、自分への備忘録を兼ねたプロダクトの技術ブログとなります。
プロダクトを作ってみた所感
仕事から帰宅後の僅かな時間でも、小さなコミットでも毎日積み重ねることで、数ヶ月で形になる事を実感した。(Firstコミットは2025-04-13 現時点でのlastコミットは2025-09-09)
コンテナ環境関連でトラブっても、エラーメッセージとDocker関連のファイルをAIチャット(Github Copilot)に添付すると、具体的な対策を示してくれるので、何時間もネットを漁ったり、沼ることは無くなった。
作成したプロダクトについて
Meshi-log 全ての人に悔いのない食生活を
機能
食事の履歴を保存するだけのアプリ、その名も『Meshi-Log』
-
身体情報、目標を設定
-
食事履歴のカレンダービュー
プロダクト制作の経緯
- 一度生成AIのAPIを使ってみたかった。
- 仕事からの帰宅後、1日30分〜1時間半程度の作業でプロダクトを作っていきたいと思った。
- 嫌がらせの中、普通に生活することが大変で、料理と飯を食うことぐらいしか楽しいことがなかった。
- 自分が使いたい。
- 正直GPTs等でも賄える程度機能だが、自分でプロダクトを作ることに意味があると思った。
開発方針
- GitHubにてPRベースの開発
- 予定が無い日はどんなに小さなコミットでもいいからコミットする
- なるべくJSは書かない
- モデル(DB)の設計をAIに提案してもらい、その設計を元に手作業でサンプルを作成
- バイブコーディングはせず、行き詰まったら、AIチャットに質問し、並走してもらう
- システムテストは書かず、スピード重視
開発環境
| カテゴリ | 内容 |
|---|---|
| OS | macOS 15.4 sequoia Debian GNU/Linux 12 bookworm(コンテナ環境) Alpine Linux v3.22(コンテナ環境) Oracle Linux Server 9.6(コンテナ環境) |
| エディタ | VScode |
| 生成AI | Github Copilot(コーディング支援・ASKモードで使用) |
| コンテナ | Docker Compose |
| 言語・Webアプリケーションフレームワーク | Ruby 3.4.2Rails 7.2.2.1JavaScript |
| データベース | MySQL 8.0redis 8.2(KVS) |
| PaaS | AWS SES(認証系メール送信サーバー) AWS S3(画像保存用ストレージ) |
| テスティングフレームワーク | RSpec 3.13 |
| Linter | rubocop 1.75.6 |
| CI/CD | Github Actions |
| API | Open AI |
| ロゴ作成 | Adobe illustrator CC |
本番環境
| カテゴリ | 内容 |
|---|---|
| Heroku | Container Registry(Dockerデプロイ) |
| Dynos | web × 1worker × 1 |
| Addons | heroku-redis:mini jawsdb:kitefin pointdns:developer |
開発手順
- タスクはObsidianのかんばんで管理
- コンテナの作成と起動
- ローカルでタスクごとにブランチを切って作業
- 作業後rspecでテスト、rubocopでLinter
- githubにpush、CI(テスト・Linterチェック)が通ったらmainブランチへマージ
- CDにより本番環境にデプロイ
- コンテナ破棄(開発ごとに使い捨て)
開発環境とデプロイ環境のイメージ
システム概要(Deepwiki-openで作成)
meshi-logは、Dockerを使用してコンテナ化されたRuby on Railsアプリケーションです。開発環境はDocker Composeによって管理され、ウェブアプリケーション、データベース、キャッシュ/ジョブキュー、バックグラウンドワーカーの各サービスで構成されています。フロントエンドはesbuildとSassによるモダンなアセットパイプラインを採用しており、Hotwire (Turbo/Stimulus) を利用してリッチなユーザー体験を提供します。
コンテナ化された開発環境
開発環境はDocker Composeによって管理されており、アプリケーションの実行に必要なすべてのサービスを定義しています。これにより、一貫した環境を容易に構築できます。
また、VolumeとBindマウントを使用してデータを永続化することで、開発タスクごとにコンテナを破棄し、コンテナに依存せず安全に開発することが可能です。
サービス構成
| サービス名 | イメージ | 役割 | ポート |
|---|---|---|---|
webapp |
カスタムDockerfile | Railsアプリケーションの実行 | 3000:3000 |
db |
mysql:8.0 |
プライマリデータベース (MySQL) | 3306:3306 |
redis |
redis:alpine |
KVS型データベース。キャッシュおよびSidekiqのブローカーとして使用 | - |
sidekiq |
カスタムDockerfile | バックグラウンドジョブの実行 | - |
サービス連携図
以下の図は、サービス間の依存関係を示しています。
-
webappとsidekiqの両サービスは、データベースとしてdb(MySQL)、ジョブキューとキャッシュのためにredis(KVS型DB)に依存しています。
ストレージサービス
画像が中心となるサービスとなるため、外部ストレージを使用しています。
ストレージにについては、AWSのS3を使用しています。
食事の画像がAWSのS3に保存され、その画像URLを元にOpen AIのAPIにリクエストを投げています。
フロントエンド
主要なライブラリ
| ライブラリ | バージョン | 用途 |
|---|---|---|
@hotwired/turbo-rails |
^8.0.13 |
高速なページ遷移とフォーム送信を実現 |
@hotwired/stimulus |
^3.2.2 |
モダンなJavaScriptコントローラ |
bootstrap |
^5.3.5 |
CSSフレームワーク |
sass |
^1.86.3 |
CSSプリプロセッサ |
esbuild |
^0.25.8 |
JavaScriptバンドラ |
@fortawesome/fontawesome-free |
^6.7.2 |
アイコンフォント |
データベーススキーマ
アプリケーションの主要機能
このアプリケーションには食事の解析、健康提案の2つの主要機能があります。
いずれも、ユーザーのデータを元にOpenAIのAPIを叩き、レスポンスを待つ処理に時間のかかる機能となるため、バックグラウンドジョブに任せ、非同期にデータを更新しています。
OpenAIのAPIと連携する2つの主要なバックグラウンドジョブは以下となります。
食事画像分析 (AnalyzeMealImageJob)
このジョブは、アップロードされた食事の画像を分析するために使用されます。openaiキューで実行され、リトライは3回に設定されています。
ジョブはmealオブジェクトを引数に取り、OpenaiVisionServiceを呼び出して画像の分析を実行し、結果でmealレコードを更新します。
処理フロー
食事提案生成 (GenerateMealSuggestionJob)
このジョブは、ユーザーの食事履歴に基づいてAIによる食事提案を生成します。AnalyzeMealImageJobと同様にopenaiキューで実行されます。
ジョブはuserオブジェクトを引数に取り、OpenaiSuggestionServiceを呼び出して提案を生成し、MealSuggestionレコードとして保存します。
フロントエンド連携
バックグラウンドジョブの処理状況をユーザーにフィードバックするために、フロントエンドでステータスをポーリングする仕組みが用意されています。
MealAnalysisStatusController
meal_analysis_status_controller.jsは、食事分析ジョブの完了状態を定期的にチェックするためのStimulusコントローラです。
このコントローラは、指定されたURLに対して定期的にリクエストを送信し、ジョブのステータスを確認します。このコントローラはapp/javascript/controllers/index.jsでアプリケーションに登録されています。
ポーリングシーケンス
このフローにより、ユーザーはページの再読み込みなしで、バックグラウンドジョブの完了を知ることができます。
Herokuへのデプロイ
Herokuへのデプロイメントフロー
このアプリケーションは、GitHub ActionsとHeroku Container Registryを使用して、継続的デプロイメント(CD)を実現しています。mainブランチにコードがプッシュされると、GitHub Actionsが自動的にHerokuへのデプロイを実行します。
デプロイのプロセスは、主に以下の3つのファイルによって定義されています。
-
cd.yml: デプロイをトリガーするGitHub Actionsのワークフローを定義します。 -
heroku.yml: Heroku上でのアプリケーションのビルド、リリース、および実行方法を定義します。 -
Dockerfile: Herokuで実行されるDockerコンテナイメージを構築するための手順を定義します。
1. デプロイのトリガー: cd.yml
cd.ymlは、GitHub Actionsのワークフローを定義しており、デプロイプロセスを開始します。
- トリガー: プッシュがmainブランチに対して行われた時に、このワークフローが実行されます。
-
ステップ:
-
actions/checkout@v4: リポジトリのコードをチェックアウトします。 -
Install Heroku CLI: Heroku CLIをインストールします。 -
Deploy to Heroku:akhileshns/heroku-deploy@v3.13.15アクションを使用してデプロイを実行します。
-
-
Herokuの認証情報:
HEROKU_API_KEY,HEROKU_APP_NAME,HEROKU_EMAILは、GitHubリポジトリのSecretsに保存されており、安全に利用されます。
2. Herokuでのビルドと実行: heroku.yml
heroku.ymlファイルは、Herokuがアプリケーションをどのようにビルドし、実行するかを定義します。これはHerokuにおけるアプリケーションの「マニフェスト」として機能します。
-
setup: アプリケーションに必要なアドオンをプロビジョニングします。-
jawsdb:kitefin: MySQL 8.0に対応したJawsDBの無料プランを使用します。 -
heroku-redis:mini: Heroku Redisアドオンを使用します。
-
-
build: アプリケーションのDockerイメージをビルドします。-
web: Dockerfile:webプロセスは、Dockerfileを基にビルドされます。 -
worker: Dockerfile:workerプロセス(Sidekiq)も同様にDockerfileを基にビルドされます。 -
config: ビルド時の環境変数を設定します。RAILS_ENV: productionやNODE_ENV: productionなどが設定されています。
-
-
release: ビルド後に一度だけ実行されるコマンドを定義します。-
bundle exec rails db:migrate: データベースのマイグレーションを実行します。これにより、アプリケーションの起動前にデータベースが最新の状態に保たれます。
-
-
run: 実行時に起動するプロセスとそのコマンドを定義します。-
web:bundle exec rails server -p $PORTコマンドでRailsサーバーを起動します。 -
worker:bundle exec sidekiq -C config/sidekiq.ymlコマンドでSidekiqワーカーを起動します。
-
3. 本番環境向けコンテナイメージ: Dockerfile
Dockerfileは、Herokuで実行される本番環境用のコンテナイメージを構築する手順を定義しています。heroku.ymlのbuildセクションによって、このファイルのproductionステージが使用されます。
-
ベースイメージ:
ruby:3.4.2がベースイメージとして使用されます。 -
productionステージ:-
ENV RAILS_ENV=productionとENV NODE_ENV=productionで、本番環境の環境変数が設定されます。 -
bundle install --jobs=4 --retry=3: 開発用やテスト用のGemは除外して、本番環境に必要なGemのみをインストールします。 -
yarn install --check-files: yarnパッケージをインストールします。 -
bundle exec rails assets:precompile: アプリケーションのアセットをプリコンパイルします。これにより、アプリケーションの実行速度が向上します。 -
CMD bundle exec rails server -p $PORT: Herokuのheroku.ymlのrunセクションで指定されたコマンドが、DockerfileのCMDを上書きして実行されます。
-





