🌎

個人開発で海外展開を前提としたWebサービスを開発しました

2024/03/25に公開

個人開発で、海外展開を前提としたWebサービスのベータ版を開発してリリースしたので、サービスの宣伝も兼ねて技術的な背景や開発を通して得られた知見を共有します。
近年円安が進んでいる中で、外貨を獲得したいというのと、国境を超えて多様なユーザーに使われるサービスを作りたいという思いで最初から海外展開を目指しました。

サービスの紹介

サービス名は「CodeBreath」です。
名前の由来にも繋がりますが、このサービスは「息をするように、日々エンジニアリングする」をコンセプトとしています。
https://codebreath.dev/

  • GitHubと連携し、ユーザーのコーディング活動を追跡・分析することで、個々の進捗を可視化し、モチベーションの向上に貢献する
  • ゲーミフィケーションを取り入れることで、ユーザーはミッションを達成しながらランクアップし、学習や開発の過程を一層楽しむことができる

ベータ版である現時点では、以下のような機能が含まれます。

  • GitHub連携
    • 認証
    • GitHubリポジトリのコミット状況集計
  • ゲーミフィケーション関連機能
    • ミッション
    • ランク
    • ランキング
  • リポジトリの活動状況の可視化
    • ヒートマップ(いわゆるGitHubの草)
    • 現在の連続活動日数やトータルの活動日数など
  • プロフィール
  • 設定など

技術スタック

技術選定の際には以下を考慮しました。

  • 低コストで運用可能
  • 使い慣れている(開発効率がいい)
  • 開発体験がいい(開発効率がいい)

技術構成図

Remix

https://remix.run/
クライアントとサーバーをRemixで実装しました。
RemixはReactベースのフルスタックWebフレームワークで、効率的なデータ取得とページレンダリングの最適化を通じて、UXを向上させることに重点を置いているのが特徴です。

Remixを選んだ理由は、既に使い慣れた技術だったからです。以前にRemixを使って、一つのプロダクトを作っていたので、ノウハウを流用できました。個人的には、Remixは初学者でも学習ハードルがあまり高くないと感じています。
アプリは、TypeScriptやTailwindCSS、Prismaを使用してコードを記述しています。

Fly.io

https://fly.io/
コンピューティングとデータベースにFly.ioを使用しています。
Fly.ioはエッジコンピューティングサービスを提供しており、アプリケーションをユーザーに近い場所で実行することで、低遅延で高速なアプリケーション体験を実現できるのが魅力です。
Remixは基本的にSSR(サーバーサイドレンダリング)での実行を想定しており、エッジコンピューティングで処理を実行することで、SSRながら低遅延で高速な体験を実現します。Remixの初期構築時に、デプロイ先の設定を行えますが、その選択肢の一つにFly.ioがあります。(初期構築時にFly.ioのデプロイに必要なファイル群を作成してくれる)

Fly.ioを選んだ理由は、上記の通り、Remixと相性がよく、無料で使用可能なプランがあったからです。(現在は料金体系が変更されているようなので、最新情報を確認してください。

最初は、コンピューティングのみFly.ioを使用し、データベースにはPlanetScaleを使用していました。しかし、最近PlanetScaleの無料プランが廃止され、最低スペックでも月に39ドル課されるようになり、売上をあげていないサービスを開発する個人にとっては手痛い費用になってしまいました。(us-central1リージョンの場合。東京リージョンは47ドル。)
そこで、Fly.ioはPostgresデータベースも提供しているので、それを利用するようにしました。

本番環境とステージング環境を作成しています。一つの環境にコンピューティング用マシンとデータベース用マシンの二つ存在するので、合計4つのマシンを作成しています。

ベータ版リリースに合わせて、基本月額29ドルのLaunchプランを契約しました。実際に運用してみないとなんとも言えませんが、コンピューティングとデータベースをFly.ioに寄せることで、今後別のサービスを開発する際にも、コスト管理がしやすく、運用コストを低めに抑えられるのではないかと思っています。

Firebase

https://firebase.google.com/?hl=ja
安定のFirebaseも使用しています。

  • GitHub認証にAuthenticationを使用
  • 画像の保存にStorageを使用

CloudRun Job

https://cloud.google.com/run/docs/overview/what-is-cloud-run?hl=ja#jobs
https://cloud.google.com/scheduler?hl=ja

CodeBreathでは、ユーザーのアクティビティをもとに、ミッションの達成状況の更新や経験値の計算、ランキングの計算などをするために、標準時の午前0時に毎日バッチ処理を実行しています。
バッチ処理をCloudRun Jobで実行し、CloudSchedulerで毎日指定時刻にジョブを実行させています。

CloudRunを選んだ理由は、低コストで運用でき、GCP自体が仕事で使い慣れているからです。
この構成はユーザー数が相当数増えない限り、無料で運用可能な計算になっています。

CodeBreathは様々な国のユーザーが使用する可能性があるので、今後、ジョブを複数作成し、エリアによって実行タイミングをずらして、どのユーザーにとってもサービスを利用しない時間帯にデータを処理することも想定しています。また、ユーザー数が増えた際にも、並列実行するタスク数を増やして効率的にバッチを実行することも可能です。

GitHub連携

現時点で、CodeBreathはGitHub連携を前提としており、GitHub上のアクティビティをサービス上で集計します。
サービスの肝であるGitHub連携ですが、セキュリティーとプライバシーに気を付けなければいけません。
CodeBreathではGitHub上のアクティビティとしてCommit日時もしくはpush日時を収集します。
対象が公開リポジトリの場合、GitHubAPIを利用し、CodeBreathが管理する定期実行ジョブで直接コミット日時を取得します。
対象が非公開リポジトリの場合、GitHubAPIを利用せずに、ユーザーに対象のリポジトリに対して以下の操作を行なってもらいます。

  • シークレットにCodeBreathのAPIを実行するために、トークンを保存する
  • push時にCodeBreathのAPIを実行するために、以下のようなワークフロー設定ファイルを配置する

非公開リポジトリに対するコミット日時をGitHubAPIで取得するには、GitHub OAuthで「repo」スコープをサービスに付与する必要があります。これは、公開・非公開リポジトリのコードの読み取り・書き込み権限など非常に強力な権限を有するので、取り扱うには非常にリスクが高いです。
GitHubワークフローでサービス側のAPIを実行し、その時点の日時を取得することによって、サービスがリポジトリの読み取りを行うことなく、必要なアクティビティを取得するようにしています。

そのため、今後、ワークフローでは実現できない追跡が必要になった場合、公開リポジトリを対象にしか提供できない機能が発生するかもしれません。

利用規約とプライバシーポリシー

利用規約やプライバシーポリシーなどの法令文書の作成は、サービスの本質ではないので、類似サービスの規約をそのまま使うなどして雑に終わらせたくなります。しかし、これらはクレーム対応の際の話し合いの土俵になったり、法律で定められたデフォルトルールが不利に働かないようにするための重要な文書なので、今回は最低限知識を身につけた上で作成していきました。
特に、海外展開するサービス特有のポイントには注意をしました。

以下の書籍を読み込んで学習をしました。すごく読みやすく、利用規約とプライバシーポリシー、特定商取引法のひな形も付属していたりと、おすすめの書籍です。
良いウェブサービスを支える「利用規約」の作り方

準拠法と裁判管轄の合意

日本に住んでいる者同士の紛争の場合、日本の法律に基づいて、日本の裁判所で手続きを行えばいいわけですが、もし、日本在住の開発者である私と海外在住のユーザーの間で紛争が発生した場合、ユーザーの居住国の法律が適用される可能性が出てきます。
このような事態を可能な限り避けるために、以下の文言を利用規約に含める必要があります。

  • 日本法を準拠法とする
  • 東京地方裁判所を第一審の専属的合意管轄裁判所とする

GDPR(一般データ保護規則)

GDPRは、EU(ヨーロッパ連合)域内の個人のプライバシーとデータ保護を規制するものです。Webサービスを通じてEU域内の個人に向けてサーヒス提供を行う場合はこれが適用され、日本の個人情報保護法とは異なる規制を受ける可能性があります。
GDPRは世界の個人情報保護関連規則の中で、比較的厳格なもので、一般的なプライバシーポリシーに記載される項目以外に、以下のような情報についても提供することが求められます。

  • 身元及び連絡先
  • DPO(データ保護責任者)の詳細な連絡先
  • データ処理の目的・法的根拠
  • データ処理の「正当な利益」
  • データの類型
  • データの受領者
  • 第三国間移転
  • 保有期間
  • データ主体の権利
  • 同意の撤回権
  • 監督期間に対して異議を申し立てる権利
  • データ提供が法令・契約上の要件であるかなど
  • データの取得元
  • 自動処理による意思決定の存在など

この中でも、「データ処理の目的・法的根拠」が特に重要です。
CodeBreathでも、ユーザーから取得した各種データについて、それぞれ処理の目的と法的根拠を明確にしました。
プライバシーポリシー

これでも十分な規約を作成できているかは正直不安で、本当は弁護士や法務の専門家に相談した方がいいのですが、お金もあまりかけられないので、一旦はヨシとしています。

ふりかえり

  • SaaSの無料プラン廃止怖い!!
    • 使い捨てのシステムの開発でなら使ってもいいけど、本格的に運用していくつもりのシステムで使うなら、本番環境で現実的に必要なリソースを見積もって適切なSaaSを選択する。(SaaSの無料プランは基本的に販促要素が大きいのでいつかは廃止されると考えるべき)
  • LLMは偉大!!
    • LLMのおかげでかなり開発効率が向上した。アイデア出しやロジックの実装、デザイン作成など様々な場面で活躍した。ミッションのアイコンもベースはChatGPTが作った。
  • ビジネス面もどんどん学習して実践していきたい
    • CodeBreathの正式版の開発や今後の新規開発では、収益を得られるように意識して開発していきたい。

今後の展望

今回ベータ版をリリースしましたが、まだまだ必要な機能が出揃っていません。
CodeBreathが目標とするのは、「日々のエンジニアリングに新たな楽しみを加え、エンジニアリングを習慣化するとともに、結果的にプロジェクトの成功を助ける」ことです。
そのために以下の三軸で機能開発を進めていくつもりです。

  • コーディングや学習、ブログ執筆などを習慣化できる
  • 自身の作業習慣についてのインサイトが得られる
  • 作業仲間との繋がりを感じられる

この方針をもとに、ロードマップを作成したので、今後はこれに沿って開発を進めていきます。並行して新しいサービスも作っていきたいです。
https://trello.com/b/HnPSq2Va

Discussion