OrbStack + Docker Compose + Claude Code 実践ワークフロー 2026 — macOSエンジニアの開発環境設計

OrbStack + Docker Compose + Claude Code 実践ワークフロー 2026 — macOSエンジニアの開発環境設計

OrbStackとDocker ComposeをClaude Codeと組み合わせたmacOS開発環境の設計を解説。CLAUDE.md記述パターン、git worktree並行開発でのポート分離、DBマイグレーション自動化まで、実際の運用ベースで書く。

エンジニアのゆとです。

OrbStackに乗り換えて、Macのメモリ問題は解決した。でも次の問題がある。「Claude Codeにコンテナ環境の文脈を正確に把握させるにはどう設計すればいいか」だ。

Docker Composeで複数サービスを動かすプロジェクトでClaude Codeを使うとき、何も設定しないとClaude Codeはサービス間の依存関係やDBの状態を把握できない。「このコマンドどこで実行すればいい?」「マイグレーションどう動かす?」を毎回聞かれる。

この記事ではOrbStack + Docker Compose + Claude Codeの三角関係を最大限に活かす設計パターンを書く。


なぜOrbStackとDocker Composeの組み合わせが強いのか

まず前提を確認しておく。

OrbStackはDocker CLIと完全互換で、docker compose up はそのまま動く。OrbStackに移行してもdocker-compose.ymlを書き直す必要はない。

重要なのはファイルI/Oの性能差だ。Docker Desktopではホストマウント(-v $(pwd):/app 形式)を使うとコンテナ内からのファイルアクセスが遅い。package.jsonの変更がホットリロードに反映されるまで2〜3秒かかるケースがある。

OrbStack はこの問題を独自のVirtioFS実装で解決していて、ホストマウントでも読み取り速度がDocker Desktopの3倍以上になる。Claude Codeがファイルを読みながら作業するワークフローでは、体感できるレベルの差が出る。


CLAUDE.mdにDocker Compose環境を記述する

Claude Codeがプロジェクトを正確に理解するためには、CLAUDE.mdへの記述が鍵になる。

特にDocker Compose環境では以下の3点を書く:

  1. 各サービスの役割(どのコンテナで何が動いているか)
  2. コマンドの実行場所(ホストで動かすのかコンテナ内か)
  3. DBマイグレーションの手順

実際のCLAUDE.md記述例

## 開発環境

Docker Compose で以下のサービスが起動する:

| サービス | ポート | 役割 |
|---------|--------|------|
| app | 3000 | Next.js アプリ(HMR有効) |
| db | 5432 | PostgreSQL 16 |
| redis | 6379 | セッション・キャッシュ |
| worker | - | バックグラウンドジョブ(BullMQ) |

起動:
```bash
docker compose up -d

アプリ操作(appコンテナ内で実行):

docker compose exec app npm run xxx

DB操作(必ずdocker compose exec db経由で):

docker compose exec db psql -U postgres -d myapp

マイグレーション:

docker compose exec app npm run migrate

このフォーマットで書くと、Claude Codeは「どのコンテナでコマンドを実行するか」を自動で判断するようになる。「`npm install` はホストで実行してください」と言わなくなる。

---

## ファイルI/Oのチューニング

OrbStackでDocker Composeを使うときに注意すべきホストマウントの設定がある。

`docker-compose.yml` でvolumesを定義するとき、デフォルトのbind mountで問題ないケースがほとんどだが、`node_modules` や `.next` キャッシュのような書き込みが多いディレクトリは**named volumeにする**のが効く。

```yaml
services:
  app:
    image: node:20-alpine
    volumes:
      # ソースコードはホストマウント(HMRのため)
      - .:/app
      # node_modules はコンテナ内のnamed volume
      - node_modules:/app/node_modules
      # .next キャッシュもnamed volume
      - nextjs_cache:/app/.next

volumes:
  node_modules:
  nextjs_cache:

こうするとホストとコンテナの境界を越えるファイルI/Oを最小限にできる。npm install の速度が体感で変わる。

OrbStackのダッシュボードから各volumeの使用量を確認できるので、肥大化したら docker volume prune で整理する。


git worktreeでの並行開発設計

Claude Codeでgit worktreeを使って複数ブランチを同時に作業するとき、Docker Composeのサービスがぶつかる問題が出る。

デフォルトではworktreeが増えるたびにコンテナ名とポートが競合する。

COMPOSE_PROJECT_NAMEで分離する

ルートに .env を置いてプロジェクト名を動的に設定する:

# worktree ごとに異なるディレクトリ名を使う
# main branch: /path/to/project
# feature branch: /path/to/project-feature-xxx

# .env(各worktreeのルートに置く)
COMPOSE_PROJECT_NAME=myapp-main  # worktreeごとに変える
DB_PORT=5432                     # worktreeごとに変える
APP_PORT=3000

ポートの割り当てを自動化するスクリプトを scripts/setup-ports.sh に置いておくと便利だ。

#!/bin/bash
# worktreeディレクトリ名からハッシュを生成してポートを決定
HASH=$(echo $(pwd) | md5sum | head -c 4 | printf "%d\n" "0x$(cat)")
BASE_PORT=$((3000 + ($HASH % 100)))

cat > .env << EOF
COMPOSE_PROJECT_NAME=myapp-$(basename $(pwd))
APP_PORT=${BASE_PORT}
DB_PORT=$((5432 + ($HASH % 100)))
EOF
echo "ポート割り当て完了: APP=${BASE_PORT}"

docker-compose.yml 側でポートを環境変数から読む:

services:
  app:
    ports:
      - "${APP_PORT:-3000}:3000"
  db:
    ports:
      - "${DB_PORT:-5432}:5432"

CLAUDE.mdにこのスクリプトの存在と使い方を書いておくと、Claude Codeが新しいworktreeをセットアップするときに自動で実行するようになる。


DBマイグレーションをClaude Codeに任せる設計

マイグレーション管理は失敗すると厄介だが、ルールを明確にするとClaude Codeが正確に動く。

CLAUDE.mdに記述すべき内容:

## マイグレーションルール

- マイグレーションファイルは `db/migrations/` に置く
- ファイル名: `YYYY-MM-DD-HHmm_説明.sql`(例: `2026-06-21-1430_add_user_roles.sql`
- 実行: `docker compose exec app npm run migrate`
- ロールバック: `docker compose exec app npm run migrate:down`
- マイグレーション後は必ず `docker compose exec app npm run seed:check` でシードデータ整合性を確認

新しいカラムやテーブルを追加するとき:
1. マイグレーションファイルを作成
2. TypeScriptの型定義を更新(src/types/)
3. テスト用のfactoryを更新(src/factories/)
の順に作業する

このルールをCLAUDE.mdに書くと、「カラムを追加して」という指示で一連の作業を正しい順番でやってくれる。マイグレーションだけ作って型定義を忘れるミスがなくなる。


OrbStack固有の便利機能

Docker Composeと組み合わせると特に便利なOrbStack機能を2つ紹介する。

ローカルドメイン

OrbStackは各コンテナにローカルドメインを自動で割り当てる。

# OrbStackが自動生成するドメイン
myapp-main_app.orb.local  → appコンテナ
myapp-main_db.orb.local   → dbコンテナ

HTTPSで https://myapp-main_app.orb.local にアクセスできる。localhost:3000 でアクセスするより、本番環境に近い動作確認ができる。

Claude CodeにはこのドメインをCLAUDE.mdに書いておく:

## ローカルURL

- アプリ: https://myapp_app.orb.local または http://localhost:3000
- DB管理: http://localhost:5050(pgAdmin)

Debug Shell

OrbStack Proの機能で、起動中のコンテナにdistroless/scratchベースのコンテナでも接続できる。/bin/sh が入っていないコンテナのデバッグに使える。

Claude Codeがコンテナ内で直接デバッグしたい場面で役立つ。


まとめ

OrbStack + Docker Compose + Claude Codeを組み合わせるときのポイントを整理する。

  • CLAUDE.md: サービス構成・コマンド実行場所・マイグレーション手順を明記する
  • named volume: node_modules.next キャッシュはコンテナ内のnamed volumeにする
  • worktree対応: .env でCOMPOSE_PROJECT_NAMEとポートをworktreeごとに分離する
  • ローカルドメイン: OrbStackの自動ドメイン機能でHTTPS環境を作る

Docker Composeを使った環境で「Claude Codeに正確に作業させるには文脈の設計が9割」というのが正直な感想だ。CLAUDE.mdを丁寧に書くほど、指示が短くて済むようになる。

OrbStackの導入・乗り換えについては以下の記事も参考にしてほしい。

OrbStack vs Docker Desktop 徹底比較 — Macのメモリを半分取り戻す方法【2026年版】
OrbStack vs Docker Desktop 徹底比較 — Macのメモリを半分取り戻す方法【2026年版】OrbStack と Docker Desktop を料金・メモリ・機能・ユースケースの4軸で比較。個人開発者が乗り換えるべきタイミングと、Docker Desktop を残すべき理由まで正直に書く。読む →
Docker DesktopからOrbStackに3ヶ月乗り換えた結果レポート — メモリ・CI連携・ハマりどころの実測記録
Docker DesktopからOrbStackに3ヶ月乗り換えた結果レポート — メモリ・CI連携・ハマりどころの実測記録Docker Desktop から OrbStack に乗り換えて3ヶ月が経過。メモリ使用量の実測値・Docker Composeの互換性・GitHub Actions連携・日常業務でのパフォーマンス変化を正直にレポート。移行を迷っている人向けの実体験記録。読む →
Docker Desktopのメモリ食いすぎ問題にMacエンジニアが終止符を打った話
Docker Desktopのメモリ食いすぎ問題にMacエンジニアが終止符を打った話MacのDocker Desktopが16GB RAMの半分を食う問題をOrbStack乗り換えで解決した実測レポート。アイドル時メモリ81%減、I/O 3倍、起動時間6分の1。Colima比較・docker-compose互換性・Apple Silicon対応・乗り換え手順まで全部書いた。読む →
← 記事一覧に戻る