Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Claude Code × git worktree で並列開発 (続き) -差分のサービスだ...
Search
NearMeの技術発表資料です
PRO
August 28, 2026
54
1
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
59
LLM + 強化学習
nearme_tech
PRO
0
32
PosthogのA/Bテスト機能の紹介
nearme_tech
PRO
1
62
AIフレンドリーなプロダクトに向けて
nearme_tech
PRO
2
65
初めてのLean言語
nearme_tech
PRO
0
100
Apache Airflow Workflow orchestration without turning cron into spaghetti
nearme_tech
PRO
2
38
実務で役立つ幾何学 ボロノイ図の基礎から グラフ・ネットワーク応用まで
nearme_tech
PRO
1
76
SQL/ID抽出タスクから考える 実践的なハルシネーション対策
nearme_tech
PRO
1
89
OpenCode & Local LLM
nearme_tech
PRO
0
330
Featured
See All Featured
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
280
Balancing Empowerment & Direction
lara
6
1.3k
How to Think Like a Performance Engineer
csswizardry
28
2.8k
Mobile First: as difficult as doing things right
swwweet
225
10k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
420
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
850
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
690
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
141
35k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
How to build a perfect <img>
jonoalderson
1
6k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
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