Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Claude Code × git worktree で並列開発 (続き) -差分のサービスだ...
Search
NearMeの技術発表資料です
PRO
August 28, 2026
3
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Claude Code × git worktree で並列開発 (続き) -差分のサービスだけを併設する-
NearMeの技術発表資料です
PRO
August 28, 2026
More Decks by NearMeの技術発表資料です
See All by NearMeの技術発表資料です
Claude Code × git worktree で並列開発 — サブモジュール構成のリポジトリで成立させる —
nearme_tech
PRO
0
42
LLM + 強化学習
nearme_tech
PRO
0
26
PosthogのA/Bテスト機能の紹介
nearme_tech
PRO
1
34
AIフレンドリーなプロダクトに向けて
nearme_tech
PRO
2
61
初めてのLean言語
nearme_tech
PRO
0
95
Apache Airflow Workflow orchestration without turning cron into spaghetti
nearme_tech
PRO
2
34
実務で役立つ幾何学 ボロノイ図の基礎から グラフ・ネットワーク応用まで
nearme_tech
PRO
1
68
SQL/ID抽出タスクから考える 実践的なハルシネーション対策
nearme_tech
PRO
1
83
OpenCode & Local LLM
nearme_tech
PRO
0
310
Featured
See All Featured
Practical Orchestrator
shlominoach
191
12k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
Speed Design
sergeychernyshev
33
2k
Optimizing for Happiness
mojombo
378
71k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
390
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
870
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
550
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.9k
Transcript
Claude Code × git worktree で並列開発 (続き) — 差分のサービスだけを併設する —
2026-08-28 第153回NearMe技術勉強会 Kenji Hosoda 0
前回(第 152回)と、そこからの拡張 [前回までの成果と課題] • 前回:`git worktree` + Claude Code `--worktree`
で作業ディレクトリを分離、並列開発を成 ⽴ • 解決策:サブモジュール構成の壁は SessionStart hook(submodule init + ポート採番)で解 • 構成:アプリ分離、DB共有でメイン環境はデグレゼロ。この⼟台はそのまま継承 • 残る課題:物量。worktreeごとのスタック1式では計算資源が⾮常にかかる [今回の拡張アプローチ] • 差分サービスのみ併設:差分のサービスだけを新設し、残りはメインスタックを使い回す • ドメインルーティング化:ポート指定からの脱却を⾏い、管理コストを削減 前回: worktree ごとにスタック 1式 main コンテナ数 × worktree 数 poc-a 今回: 差分のサービスだけを併設 poc-b メインスタック コンテナ数 + 差分ぶんだけ variant A variant B
なぜ今これが必要になったか • AI コーディングで、1機能あたりの実装時間が大きく縮んだ • 結果、ボトルネックが「書く」から「並行して進める」「確認する」に移った ▼ どちらも「メインブランチが動いたまま、別のブランチ版も動いていてほしい」という要求 • 複数の機能開発を同時に⾛らせたい(エージェントに並⾏作業させると特に)
• PR が量産され、レビュー時の動作確認の回数も増えた
前提: マイクロサービス構成のローカルスタック • バックエンドはマイクロサービス構成。ドメインご とに GraphQL の API が分かれている •
その前段に BFF Gateway が立ち、複数の API を1つのスキーマに束ねる • フロントは用途別に複数(利用者向け / ドライ バー向け / 管理者向け) • ローカルでは、これらをまとめて1つの compose スタックとして立ち上げている • 「1機能の確認」でも、動かす必要があるのはス タック全体 利用者向け web ドライバー向け web 管理者向け web BFF Gateway(GraphQL を1つのスキーマに束ねる) user-api ride-api payment-api … DB 「1機能の確認」でも、動かすのはこの一式
検討した方法と、採用しなかった理由 • ポート採番を続ける ◦ サービス × 環境の組合せぶん配ることになり、覚えられない • スタックを丸ごと複製 ◦
目的は満たすが、CPU とメモリの消費が差分に見合わない • サービスメッシュ(Istio 等)を入れる ◦ ローカル開発の入口整理には過剰 • リクエストヘッダで振り分ける ◦ フロント・クライアント側の全面改修が必要 • リバースプロキシの設定を手書き ◦ 環境の増減のたびに人が書き換えることになる 採⽤: Docker のラベルから設定を⾃動⽣成するリバースプロキシ(Traefik)
差分のサービスだけをメインスタックに併設する( variant) • 指定したサービスだけをブランチ版のコンテナと して起動し、メインスタックに併設する • メインスタックはメインブランチのまま動き続ける • ブランチ版は別のホスト名で見る http://localhost/
メインスタック (メインブランチ) http://feat-a.localhost/ variant "feat-a" http://feat-b.localhost/ variant "feat-b" 同じマシン上で同時に動く
仕組み • メインスタックと同じ Docker ネットワーク上に作 る、2つ目の compose プロジェク • 名前を指定したサービスだけがブランチ版のコ
ンテナとして起動する • 指定していないサービス(他の API、web、DB など)は、コンテナ名の解決がそのままメインス タックのコンテナに当たる • なので、スタック2つ分ではなく、コンテナ数個分 のコストで済む • コンテナ名とイメージタグには variant 名の接頭 辞を付けて、衝突を避ける 同じ Docker ネットワーク compose project: main compose project: feat-x ride_api ride_api user_api web db 解決 web 指定しなかったものは メイン側のコンテナに 解決される 起動するのは差分の 1コンテナだけ
使い方① : 並行した機能開発 # 0. 一度だけ: 新しいルーティング設定でコンテナを作り直す ./dev.sh up #
中身は docker compose up -d(設定を再生成してから実行) ./dev.sh variant up feature-a ride_api --branch feat_a ./dev.sh variant up feature-b user_api --branch feat_b ./dev.sh ps # 起動中の variant と、その URL を一覧表示 • `--branch` を省くと variant 名がそのままブランチ名になる • リポジトリごとにブランチ名が違うときは `<svc>=<branch>` で個別指定 • 存在しないブランチは(新規作成せず)拒否する ◦ たいていタイプミスなので • (別途AI用のスキルは用意したが、まずは素で使い方をキャッチアップしてほしい)
使い方② : PR の動作確認 ./dev.sh variant up pr1234 \ --pr
https://github.com/<org>/ride-api/pull/1234 \ --prod ride_api # → 開くべき URL がサマリーに表示される ./dev.sh variant down pr1234 # 確認が終わったら片付け • PR の URL からサービスとブランチの両方を解決して fetch する • `--prod` はブランチをビルドしたリリースイメージで起動する ◦ レビューは「動かす」のが主目的なので、ビルド可能性の確認も同時に済む • 複数リポジトリにまたがる PR も、`--pr` を並べて1つの variant にまとめられる
どの URL を開くか ホスト ページ API パス( /graphql ほか) <name>.localhost
利用者向け web 利用者向け BFF Gateway driver.<name>.localhost ドライバー向け web 利用者向け BFF Gateway fleet.<name>.localhost 管理者向け web 管理者向け BFF Gateway • • • • メインスタックは同じ構成を `localhost` / `driver.localhost` / `fleet.localhost` で持つ variant は「実際に起動したサービスのぶんだけ」ルートを持つ どのホストのどのパスが自分のものかは `variant up` / `variant ls` / `ps` が表示する variant up時にどのホストを立ち上げるかを指定することも可能
Traefik によるルーティングについて • • • • variant を成立させているのは、ほぼ全部このレイヤー 入口は Traefik
1つ。ホスト名とパスで、どのコンテナに渡すかを決める ルーティング規則は設定ファイルのデータとして持ち、コンテナのラベルに展開する コンテナが増減すれば、Traefik が自動で設定を読み直す
入口をホスト名に統一した理由 • 前回はポートオフセットで分離していた(`:3000` / `:3100` / `:3200`) • 環境が増えるほど「どのポートが何か」を覚える必 要が出る
• variant を足すと、サービス × variant の数だけ ポートを配ることになる • ホスト名なら `<name>.localhost` を掘るだけで増 やせる • `*.localhost` は DNS 設定なしでループバックに 解決される ◦ おまけに、Cookie やオリジンの挙動が本番構 成に近づく Before: ポート採番 After: ホスト名 localhost:3000 localhost localhost:3100 feat-a.localhost localhost:3200 feat-b.localhost … … 環境 × サービスの 組合せぶん増える 名前を掘るだけで 増やせる
ルーターの組み立て方 • ホストは完全一致、パスは前方一致。同じホスト 内ではパス付きを優先させる ◦ そうしないと `/graphql` がページ側に吸い込 まれる リクエスト
• 宛先は同じスタックでなくてよい。ここが variant の肝 # メインスタック Host(`fleet.localhost`) → 管理者向け web Host(`fleet.localhost`) && PathPrefix(`/graphql`) → 管理者向け Gateway (優先) # variant(起動したのは API 側だけ) Host(`feat-x.localhost`) && PathPrefix(`/graphql`) → feat-x の Gateway Host(`feat-x.localhost`) → メインスタックの web • 誰も名乗っていないホスト名はどのルーターにも 当たらず、404 になる feat-x の Gateway (ブランチ版) feat-x.localhost/graphql Traefik feat-x.localhost/ メインスタックの web (そのまま) 同じホスト名でも、パスごとに行き先を分けられる — 宛先は別のスタックのコンテナでもよい
注意点 • DB はメインスタックと共有(前回と同じ制約) ◦ マイグレーションは全員に効く • variant は自分の中でしか経路を張り替えない(variant に含めていないサービス経由のリクエス
トはメイン側に届く) • `--pr` は fetch するが、ローカルブランチは移動しない(未 push のコミットを守るため) • variant 名はホスト名用に正規化される(`feat_x` → `feat-x`) • 作業内容そのものなので、worktree は `variant down` では消さない
やってみた所感 • サービス間にまたがる整備は、これまで「面倒だから後回し」になりがちだった ◦ 複数リポジトリ、compose、プロキシ設定と、触る範囲が横断的すぎる • AI コーディングでツール開発のコストが下がり、そこに手を入れられるようになった ◦ 開発環境そのものを改善する、という選択肢が現実的になった
◦ AI実装を振り返ると、今回の実装は自分1人で最後までやり切れる自信はない • 一方で、AI に任せきりでは終わらなかった ◦ 敵対的レビューのループを何往復もした ◦ 実際に挙動を調べて分かった不具合もあった ◦ 検証のハーネスを整えることが重要だと感じた
まとめ • 前回の worktree 並列開発を、CPU とメモリを食い潰さない形へ拡張した ◦ 「差分のサービスだけを立て、残りはメインスタックを使い回す」ようにした ◦ AI
コーディングで、並行開発と PR 検証の回数が増えたので必要性が増した • それを可能にしたのが、ドメインルーティング(Traefik) ◦ ホスト完全一致 + パス優先でルールを組み、コンテナのラベルから自動生成する ◦ 1つのホストの中で行き先を分けられるので、少ないコンテナで済む • AI 開発で顕在化した課題を、AI で解決するという時代になった
Thank you 16