PR単位で使い捨てるカイポケコネクトのpreview環境の設計と運用

こんにちは、エス・エム・エスでカイポケコネクトのSREをしている小笠原翔太です。

2026年7月10日に開催されたSRE NEXT 2026のスポンサーセッションで、「PR単位で使い捨てるカイポケコネクトのpreview環境の設計と運用」というタイトルで発表しました。 発表スライドも公開していますが、せっかく取り組みについて文章をまとめたのでテックブログにも展開しようと思い、まとめ直したものがこちらの記事となります。発表内容に加えて、ブースで展示していた現在のpreview環境のアーキテクチャについての補足説明も加筆しているので、そちらは発表との差分となっています。

はじめに

全体の話はひとことでいうと、既存プロダクトにPR単位で使い捨てられるpreview環境を導入し、1年間運用してきた話 です。

目次

カイポケコネクトと開発フェーズ

カイポケコネクトとは

最初に、私たちが扱っているシステム「カイポケコネクト」は、介護/障害福祉事業者向け経営支援を行うSaaSプロダクトです。

システムアーキテクチャ

カイポケコネクトのシステムアーキテクチャは、拡張性と独立性を保つためドメインごとにアプリとDBを分割して設計しています。

利用されている技術スタックと本番系の基盤構成は次のとおりです。

レイヤー 技術スタック 本番系の基盤構成
フロントエンド React / Next.jsによるSPA CloudFront + S3
バックエンド Kotlin / Spring Boot / GraphQL ECS Fargateでホスティング。5つのタスクでGraphQL APIを構成
DB PostgreSQL RDS Aurora PostgreSQL

また、本体サービスとは別の複数の社内サービスとも連携しており、バックエンドのコンテナ数から考えると中規模サイズのシステムと捉えてもらうと良さそうです。

開発フェーズ

プロダクトは初期の開発フェーズが完了し、プロダクトの価値を拡大する「機能追加・サービス拡大フェーズ」へ移行しようとしているタイミングでした。 そのため、プロダクト開発の生産性を支えるために機能開発を加速させる必要があったというのが背景です。

当時のリリースフロー

そのような開発の事情があるなかで、当時のリリースフローは以下のようになっていました。

release_train_gaiyou
当時のリリースフロー

デプロイ先のAWS環境はDev, QA, Staging, Productionの4つ用意してそれぞれ使い分けていました。

まず開発フェーズでは、開発者がPRを用意してテストが通ればmainにマージしてDev環境にデプロイしていました。Dev環境は開発者が最初にデプロイするAWS環境で、少し壊れやすいのですがアプリの動作検証や基盤の構成変更の検証を行う用途で利用されていました。

一方で、本番系へのリリースフェーズでは、それとは別でリリース担当やリリースマネジャーが主導してデプロイする方式を取っていました。

具体的には以下の流れでリリースが行われていました。

  1. リリース担当がリリースするrevisionを決めてコードフリーズを行い、そのrevisionでQA環境へデプロイする
  2. 全QAメンバーがQA環境を占有して検証作業を実施
  3. リリース担当がリリースタグを作成し、Staging環境へデプロイする
  4. リリース担当がテストランナーでE2Eテストを実行する
  5. リリース担当がリリースタグを作成し、Production環境へデプロイする

QA環境はバージョンを固定して検証を行うための専用環境、Staging環境はE2Eテストを実行して意図しないデグレが発生しないことを保証するための環境という建付けでした。

つまり、いわゆるリリーストレイン方式でリリースしていました。

リリーストレインの課題

このプロジェクトにおけるリリーストレインには大きく以下3つの課題がありました。

1. リリース周期が長い

最も大きな課題はリリース周期が長いことです。このプロジェクトのリリースサイクルは2週間に一度でした。 開発スピードに対してリリースサイクルが長いため、価値提供の大きなボトルネックになっていました。またリリース時には2週間分の差分がまとめて本番へ反映されます。そのためリリースのタイミングで事故が起きやすく、問題発生時の切り分けも難しい状態でした。

2. QA環境の利用が詰まる

次の課題としてはQA環境の利用が詰まるという問題がありました。QA環境は検証用の占有環境として利用され、かつ全QAメンバーが直列に検証作業を行うためどうしても長期間ロックされてしまいます。結果的に検証期間が長引き、当時は1週間ほど環境を確保するようになっていました。 検証作業を効率的に実施できず、その間は新しいリリースもブロックされる構造になっていました。

そのため、今後開発を加速させようとしたときに、ここの詰まりによってスケールできなくなることが容易に想像できました

3. 担当者の負担が大きい

リリーストレインのもう1つの問題として、取りまとめを行う人の負担が大きいという人的な問題もありました。リリース担当やリリースマネージャーがリリースを主導する必要があるのですが、そこに運用作業とリスク管理の負荷が集中していました。 ミスを防ぐための手動プロセスや手順も増えがちで、運用が重厚になっていました。さらに、リリースされる差分のすべてを把握することが困難でした。そのため、問題発生時の対応に手間取ったり、チームをまたいだ調整コストが増えたりして、担当者を疲弊させていました。

解決策: 検証作業を分離して並列化する

解決策として考えたのは「リリースフローから検証作業を分離して並列化する」ことです。

以下の図は検証作業を分離・並列化したときのリリースフローの概念図です。

release_train_solution
検証作業を分離・並列化したリリースフロー

これまでリリースフェーズで行っていたQA環境での検証作業をすべて開発フェーズに移行しています。 開発フェーズで開発者がPRを作成したあとに専用の検証環境を立ち上げ、QAメンバーがPRごとに検証作業を並列で実施できるようにします。

そして、リリースフェーズでは、Dev環境にデプロイした後は毎日定時にGitHub Actionsのscheduled workflowを起動します。このジョブはStaging環境へのデプロイからE2Eテストの実行、production環境へのデプロイまでを連続して実行する軽量なワークフローです。 また、リリースフラグを導入することで、PO(プロダクトオーナー)が任意のタイミングで新機能をリリースできるようにします。

この方式に変更することで次の効果を狙います。

  1. リリースが毎日できる:隔週から毎日へと頻度が上がり、価値提供が高速化。デプロイごとの変更差分が小さくなり、原因特定も容易になる
  2. QAのシフトレフトと並列化:検証作業を開発フェーズに移すことでリリースを安定化させ、チームや機能ごとに検証作業を並列化することで詰まりを解消する
  3. プロセスの軽量化:重厚なリリース手順を廃止し、リリースフローを自動化・軽量化する。リリースフラグを導入することでデプロイと新機能の有効化(機能リリース)を分離する

先ほど紹介したリリーストレインの主要課題をすべて解決できるようになっています。

preview環境をどう設計したか

先ほど述べた、リリース改善施策実現に必要な構成要素の1つが、検証作業を行うための環境(私たちはこれをpreview環境と命名)でした。 この章ではそのpreview環境をどう設計したかについて説明します。

必須要件

まずQAプロセスで必要な要件は以下3つでした。

  • 十分な数の環境を容易に作れること
  • 利用チームが任意のバージョンをデプロイできること
  • DBを使い捨てできること ーデータが汚れることを気にせず占有して使えること

インターフェース設計

次に利用者のインターフェースの設計についてですが、こちらはVercel等のSaaSの開発者体験を参考にして以下のように設計しました。

  • GitHubのイベントをトリガーに、preview環境を自動で構築・更新・破棄する
  • PRのコメントに自動で各種アクセス情報を付与する

以下はpreview環境を立てたPRのサンプルです。

preview_sample
preview環境を立てるPRのサンプル

PRにラベルを付けると環境構築が始まり、完了するとbotがコメントでアクセス方法を案内する、という開発者体験になっています。

このようにインターフェースを作った理由は、以下を狙ったためです。

  • 開発者とQAのスムーズな連携:開発者がPRに実装をまとめ、それをQA担当者へ渡すことでスムーズに検証作業に移ることができる
  • ライフサイクル管理のしやすさ:環境がPRに紐づくため、不要な環境の消し忘れを防いだり、クリーンな環境管理が可能になる

アーキテクチャ

次にpreview環境のアーキテクチャを紹介します。全体像は以下のようになっています。

architecture_neon_version
preview環境のアーキテクチャ全体図

デプロイフロー

まず、preview環境のライフサイクルはGitHub Actionsのワークフローで以下のように管理します。

  • PRにpreviewラベルを付与: PRの先頭のコミットハッシュを利用して環境を構築する
  • PRにコミットをプッシュ: 差分が入ったコンポーネント(FE/BE/DB)のみ更新処理を行う
  • PRをマージ、クローズまたはpreviewラベルを外す: 環境を削除する

サービス構成

次にサービス構成ですが、preview環境ごとにフロントエンド/API/DBを1セットずつ用意するようになっています。

ドメインは https://preview-N.kaipoke.com(NはPR番号)を環境ごとに払い出しており、そこからアクセスできます。

フロントエンドはSPAなので、シンプルにCloudFrontとS3で配信しています。リクエストのホスト名に応じてアセットを出し分けるようにLambda(CloudFunction)を挟んでいます。

APIへのアクセスはCloudFrontとALBを介してmirage-ecsコンテナのproxy機能でハンドリングされ、ホスト名ごとにリクエストを各環境に振り分けています。環境ごとにバックエンドとDBが1セットずつ用意されており、バックエンドのECSタスクはmirage-ecsで、DBはSaaSのNeonでそれぞれ構築・管理しています。

なお、バックエンドは一環境あたりECSタスクが全部で5個動いており、内部でGraphQLのfederationを組む構成です。 モニタリングは本番系と同じくDataDogを利用して、トレースやログ、基盤のメトリクスを確認できるようにしています。

このような仕組みによって、PRごとの環境をAPIやDBまで独立した形で複数個準備できるように作っています。 参考情報ですが、環境の初期構築にかかる時間は2026/07/14時点で10分程度です。

設計時に考えたこと

設計にあたっては、以下3つの原則を守るようにしていました。

  • 要件が不明確なうちから作り込まない:初期段階での過剰な設計や実装を避けるため
  • 運用・開発の負担が少ない技術を選ぶ:当時はアプリ開発者のリソースが逼迫しており、開発者の負担を極力抑える必要がありました
  • 最初から完璧を目指すのではなく継続的に提供価値を高めていく仕組み作りに使えるSREのリソースが当時少なかったため、小さく作って継続的に提供価値を高めていく方針を採用

運用してどうだったか

実際に1年ほど運用してどうだったか、振り返っていきます。

狙いどおりリリース頻度を高められた

まず当初の狙いにしていたリリース頻度を高めることには成功しました。 以下は月別のデプロイ回数の推移を表したグラフです。

release_graph
月別デプロイ回数の推移

リリース方式を切り替えた2025年10月ごろから、月2回だったデプロイが月20回前後まで増えました。営業日は毎日リリースできるようになったことがわかります。 これはpreview環境以外の施策との合わせ技による成果ではありますが、サービス拡大期の開発効率の向上に貢献できたと考えています。

段階的に改善しながら育てた

そして、設計方針に従ってpreview環境は導入後に要件を適宜見直しながら改善しました。 以下のグラフはpreview環境に関するPRの月別件数推移を表しています。

preview_pr_graph
preview環境に関するPRの月別件数

全体のタスク量は多く、PR総数も結果的に200件超となっていたのですが、対応を段階的に行うことで少人数(設計から導入初期までは担当一人)でも早期に仕組みを開発に展開でき、その後の改善も継続することができました。設計時に置いた「小さく作って継続的に改善する」という原則が、うまく機能したと感じています。

結果的に利用が伸びた

結果的にpreview環境の利用数は順調に伸びました。以下は月別のpreview環境を利用したPRの件数推移のグラフです。

preview_use_pr_graph
preview環境を利用したPRの月別件数

導入当初は80件ほどだった利用件数が2026年6月は160件程度まで利用が伸びていることがわかります。 あとでも触れますがこれは当初想定の用途以外の利用が増えたことも理由となっています。

運用してわかったこと

次に運用してわかったことや気付きについて大きく3つ紹介します。

1. 複製機構の利用技術についてわかったこと

今回、バックエンドの複製にはmirage-ecsというコンテナ管理の軽量なOSS、DBの複製にはSaaSのNeonを使いました。

まずmirage-ecsは、既存のECS Fargate構成とデプロイの仕組み(ecspresso)にアドオンする形で導入できました。ecspressoの作者が作ったツールのため、親和性が高くデプロイの仕組みをそのまま維持することができました。 ツール導入で学習すべき新しい概念が少なく、メンテナンスも簡単で、開発チームへの負担を最小限に抑えながら導入できたのは非常によかったです。現在まで、他ソリューションへの置き換え検討が必要となる問題も出ておらず、安定して運用できています。

次にNeonですが、直感的で扱いやすいWeb UIや高速なブランチ機能、各種管理機能が充実しており、DB複製機能の初期導入にかかる工数を大幅に削減できたのは良かったです。 一方で、サーバ配置先の制約による性能課題がありました。DBの配置先は最寄りでもSingaporeリージョンのため、SQL実行時のレイテンシーが大きくなり、結果として一部のページで表示に時間を要する点が課題として残ってしまいました。 機能検証においては無視しても問題ないということでしばらくはそのまま利用していましたが、動作がもっさりするのでなんとかしたいという声が多く出る状況でした。

そのため、現在はtokyoリージョンに立てたAurora Serverless v2(RDS)を利用する方式をメインに運用しています。付録にてそちらのアーキテクチャについては補足します。

2. 複製「できない」外部サービスとの付き合い方が難しい

2つ目の気づきですが運用してみて実感したのは、プロダクト本体の複製よりも、複製できない外部サービスの扱いが難しい、ということです。

本体の複製は開発チームでコントロールできるのですが、利用している外部サービス(連携する社内サービス含む)には様々な制約があり、それぞれ妥協案を作って運用していく必要がありました。

例えば認証基盤については契約プランの制約でテナントを新規作成できなかったため、既存テナントに相乗りする形で対応しました。結果的に(特に不便なく運用できているものの)Dev環境のDBをコピーする方式を選択せざるを得なくなりました

ある社内サービスではアーキテクチャ上の制約により、環境複製の難易度が高くすぐには実現できませんでした。結果的に既存環境に相乗りし、preview環境向けのデータを識別できるようにアプリを改修してもらい、運用でカバーする形になりました

また他の社内サービスでは、契約プランや予算管理上の制約があるため環境の複製ができないため、特定のpreview環境にのみ期間限定で連携するというような運用になりました。

これらの外部サービスに共通する課題は2つあります。1つは、連携が増えるたびに運用の取り決めや調整を個別に行う必要があり、対応コストの増加につながる点です。もう1つは、自チームだけではコントロール・解決できない他部署・他チームの仕様や予算制約が絡むケースも多く、難易度を引き上げている点です。

preview環境を有用な状態で維持するためには外部のサービスをうまく検証用途で動かし続けるための工夫という、技術以外の課題をクリアしていく必要がある点に注意が必要だと強く感じました。

3. preview環境の想定外な需要が見えた

3つ目の気づきはpreview環境の想定外な需要が見えたことです。

当初はQAプロセスでの利用を想定していたのですが、実際は全体の8割が開発チームの自主的な動作確認・検証目的で利用されていました。QA引き渡しでの利用は予想に反して全体の20%にとどまっていたのです。

開発者のユースケースには例えば以下がありました。

  • リスク回避:Dev環境へのデプロイ前の早期リスク検知
  • DB migrationの確認:DB migrationの簡単で安全な検証に利用
  • AIを活用した並列開発:複数PRを互いに影響させず同時に検証
  • ローカル代替:一時的にローカルがうまく起動できない場合などに代替の検証環境に利用

つまり「容易に立てられる検証環境」の存在自体が、開発体験(DX)にとって実は大きな価値になっていることが運用してから初めてわかりました。設計時は実際にどのくらい使われるか見えておらず、これは運用後の一番大きな気付きでした。

まとめ

既存プロダクトにpreview環境を導入・運用して見えてきたことは、次の3点です。

  • 環境運用の実現性:今回の技術スタックでも、中規模システムのpreview環境は十分に運用できることがわかりました。少人数で運用でき、開発負担も小さく抑えることができました
  • 外部連携の課題:本体の複製以上に、複製できない外部サービスとの連携設計が重要になることがわかりました
  • 導入後の進化が大切:今回のように導入してから改善していくアプローチでは、運用に乗ってからの継続的な改善こそが本番となります。プロダクトの成長に合わせて育てていくことが重要です

preview環境というコンセプト自体は目新しくありませんが、既存プロダクトへ導入して1年間運用してきた知見が、読んでいただいた方の参考になれば嬉しいです。

なお、発表資料はSpeaker Deckで公開していますのでそちらも適宜参照してください。

付録: 現在のアーキテクチャの紹介

当日の発表スライドではお見せできなかったのですが、ブースで展示・紹介していた現在のアーキテクチャは以下のようになっています。

architecture_rds
現在のアーキテクチャ全体図

先に紹介したアーキテクチャとの違いはDBの複製機構がNeonからAurora Serverless v2(RDS)を利用した形に変わっているところです。

サービスごとに1つインスタンスを用意し、preview環境ごとに内部的にPostgreSQLのデータベースを作り、dump/restoreでDev環境のデータを流し込んで作っています。

Neonで利用者によく使われていたWeb UIについては、自作して提供しています。

web_studio_sample_page_v2
Web UIの画面サンプル(接続ページ)

web_studio_sample_edit_page
Web UIの画面サンプル(テーブルビュー)

データベースの中身を気軽に閲覧したり、テーブルの値をGUIで編集する、SQLを実行するなどの機能を持った軽量なDBのwrapperツールとなっています。以前は自力でこのようなツールを作るのは工数的に難しかったのですが、生成AIの力を借りることで要件の緩い社内ツールであれば数日で作成できるようになっていて大変ありがたい限りです。

なお、RDS方式はNeonと比較すると新しいデータベースを作るのにかかる時間は少し大きくなっています。これはdump/restoreで複製を行っているためで、現状は最大4分程度かかっています。データ量が増えるとCopy on Write方式でクローンするNeonに優位性が出る可能性もあり、このあたりは利用実体を確認しながら都度調整していく必要があると考えています。