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
モノレポ × DevContainere 設計パターン
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
abimaru
December 19, 2025
Technology
490
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
モノレポ × DevContainere 設計パターン
スリーシェイク
エンジニア勉強会用資料です。
abimaru
December 19, 2025
More Decks by abimaru
See All by abimaru
SAM + FastAPI + Mangum でお手軽サーバーレス
kugimiya
0
470
Other Decks in Technology
See All in Technology
CTO Night|NotionのAIエージェントとFDE
kzkhykw1991
0
220
QA4AI 2026-Oct 生成AI時代の品質保証
tokuty
1
890
アウトプット初心者、半年間のふりかえり
4o1sobblue
0
440
ソフトウェア ファクトリー - 再現性のあるソフトウェアの工場づくり / Software factory
iktakahiro
6
5k
Active Record Connection Adaptersにおける長年の課題に再び取り組む
yahonda
0
200
日本語に強いオープンな大規模言語モデル「LLM-jp」
odashi
5
1.1k
Post AI時代のリファクタリング実践記 / Refactoring in the post AI era
kaminashi
1
270
JAWS-UGグッズ職人仕事の流儀
kentapapa
0
120
古い指輪から広がった JAVA コミュニティ とのつながり
yamad
0
130
事業成長とデータ活用を止めないためのマネジメントへ挑戦
hiracky16
0
400
How to Design Configuration for Rails Applications
willnet
1
830
SAENM ~Jupyterで残すPoCの試行錯誤、未来の自分と仲間を助ける記録!~
terapyon
0
120
Featured
See All Featured
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Practical Orchestrator
shlominoach
192
12k
Visualization
eitanlees
153
17k
Chasing Engaging Ingredients in Design
codingconduct
0
360
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.7k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.5k
Designing for humans not robots
tammielis
254
26k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Building Better People: How to give real-time feedback that sticks.
wjessup
371
20k
Believing is Seeing
oripsolob
1
240
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
Transcript
モノレポ × DevContainer 設計パターンガイド どちらのパターンを選ぶべきか 2025/12/19 エンジニア勉強会 釘宮 大知
今日お話しすること 1. 前提知識 - VS Code ワークスペースとは 2. 2つのパターン -
単一 vs サービス別 DevContainer 3. 詳細比較 - 開発体験・拡張機能・運用面 4. パターン2を選ぶ理由 - サービス別DevContainerの利点 5. 実装例 - 具体的なファイル構成 6. まとめ 2
この発表で解決できること こんな悩みを持っていませんか? モノレポでDevContainerをどう構成すべきか わからない 拡張機能が正しく動作しない frontend/backendで異なる言語を使うときの 最適解がわからない この発表で持ち帰れるもの 2つのパターンの違いと選び方 ワークスペースと拡張機能の関係
パターン2(サービス別)の具体的な実装方 法 目標:チームに最適なDevContainerパターンを選択できるようになる 3
前提知識: VS Code ワークスペースとは ワークスペース = VS Code が開いているフォルダ VS
Code で /my-project を開く ↓ /my-project がワークスペースになる ↓ - ファイルツリーのルートは /my-project - ターミナルの初期ディレクトリは /my-project - 拡張機能は /my-project を基準に動作 4
なぜワークスペースが重要か 多くの VS Code 拡張機能は、ワークスペースのルートを基準に動作します。 拡張機能 参照するファイル 期待する場所 ESLint .eslintrc
ワークスペースルート Prettier .prettierrc ワークスペースルート TypeScript tsconfig.json ワークスペースルート Tailwind CSS tailwind.config.js ワークスペースルート モノレポの課題: ルートを開くと設定ファイルが複数の場所にあり、拡張機能が正しく動作しないことがある 5
設定で回避できるが、面倒 .vscode/settings.json で設定ファイルのパスを指定すれば動かせる { "eslint.workingDirectories": ["frontend", "backend"], "prettier.configPath": "frontend/.prettierrc", "typescript.tsdk":
"frontend/node_modules/typescript/lib" } この方法の問題 拡張機能ごとに設定が必要 frontend/backendで設定が異なると複雑化 新規拡張機能追加時に設定追加が必要 ワークスペースを分ける利点 拡張機能がデフォルトで正しく動作 .vscode/settings.json がシンプルに 設定ミスによるトラブルが減る 6
DevContainer とワークスペースの関係 DevContainer では workspaceFolder で、コンテナ内のどのパスをワークスペースにするかを指定します。 { "workspaceFolder": "/app/frontend" }
この設定により: VS Code は /app/frontend をワークスペースとして開く ファイルツリーには /app/frontend 以下が表示される 拡張機能は /app/frontend を基準に動作 7
ワークスペースの仕組みはわかった。 では、モノレポでどう構成する? → 2つのパターンを紹介 8
モノレポの DevContainer、2つのパターン monorepo/ ├── frontend/ ├── backend/ └── compose.yml パターン1:
単一 DevContainer(全部入り) .devcontainer/ └── devcontainer.json ← 1つだけ モノレポ全体を1つの DevContainer で開く パターン2: サービス別 DevContainer .devcontainer/ ├── frontend/ │ └── devcontainer.json └── backend/ └── devcontainer.json 各サービス用に別々の DevContainer を用意 9
パターン1: 単一 DevContainer の設定 { "workspaceFolder": "/app", "customizations": { "vscode":
{ "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "ms-python.python", "golang.go" ] } } } 特徴: 全ての言語・ツールの拡張機能を一度にインストール 10
パターン2: サービス別 DevContainer の設定 // frontend/devcontainer.json { "workspaceFolder": "/app/frontend", "customizations":
{ "vscode": { "extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] } } } // backend/devcontainer.json { "workspaceFolder": "/app/backend", "customizations": { "vscode": { "extensions": ["golang.go"] } } } 特徴: 各サービスに必要な拡張機能のみをインストール 11
各パターンの詳細比較: 開発体験 観点 パターン1(単一) パターン2(サービス別) ファイルツリー 全ファイル見える 担当サービスのみ 拡張機能 全部入り
必要なものだけ ターミナル コンテナ内 コンテナ内 Git操作 コンテナ内で可能 ホスト推奨 12
各パターンの詳細比較: 拡張機能の動作 観点 パターン1(単一) パターン2(サービス別) 設定ファイル検出 複数あると混乱の可能性 正しく検出 言語サーバー 全言語が起動
必要な言語のみ メモリ使用量 多い 少ない 13
各パターンの詳細比較: セットアップと運用 観点 パターン1(単一) パターン2(サービス別) 初期構築の手間 少ない 中程度 設定の重複 なし
一部あり VS Code起動 1ウィンドウ 複数ウィンドウ可 14
チーム規模との相性 チーム構成 おすすめパターン 1人で全部開発 パターン1 少人数で全部触る パターン1 担当が分かれている パターン2 言語が大きく異なる
パターン2 💡 チームの状況やプロジェクトの特性に合わせて選択 15
パターンの違いはわかった。 なぜパターン2を選ぶのか? → パターン2(サービス別)が有効なケース 16
パターン2を選ぶ理由1: 拡張機能の最適化 例: TypeScript + Go + Python のモノレポ monorepo/
├── frontend/ # TypeScript, React ├── backend/ # Go └── data/ # Python パターン1(単一) { "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "golang.go", "ms-python.python", "ms-python.vscode-pylance" ] } → 全ての言語サーバーが起動 パターン2(サービス別) // frontend { "extensions": ["vscode-eslint"] } // backend { "extensions": ["golang.go"] } // data { "extensions": ["ms-python.python"] } → 必要な拡張機能だけ 17
パターン2を選ぶ理由2: 担当領域への集中 ファイルツリーに関係ないコードが表示されないため、集中しやすい パターン1: 全ファイル表示 ├── frontend/ │ └── src/(100ファイル)
├── backend/ │ └── src/(100ファイル) └── ... パターン2: 担当分だけ表示 frontend の DevContainer: └── src/(100ファイル)← これだけ 18
パターン2を選ぶ理由3: 疎結合開発との相性 frontend と backend を疎結合で開発する場合、それぞれが独立した開発環境を持つのは自然 frontend 開発者は frontend の
DevContainer を使う backend 開発者は backend の DevContainer を使う 必要なときだけ両方起動 19
トレードオフ: Git 操作 パターン2 では、ワークスペースがサブディレクトリになるため、Git 操作がしにくくなる 対処法: Git 操作はホスト側で行う または、ターミナルで
cd /app してから操作 20
パターン2の利点はわかった。 実際にどう実装する? → 具体的なファイル構成と設定例 21
パターン2の実装例: 全体構成 22
ディレクトリ構成 . ├── .devcontainer/ │ ├── backend/ │ │ ├──
devcontainer.json # backend用の設定 │ │ └── compose.yml # backend用のオーバーライド │ └── frontend/ │ ├── devcontainer.json # frontend用の設定 │ └── compose.yml # frontend用のオーバーライド ├── backend/ # バックエンドコード ├── frontend/ # フロントエンドコード ├── compose.yml # 共通のDocker Compose設定 └── Dockerfile.local # 共通の開発用イメージ 23
Dockerfile.local(共通の開発用イメージ) FROM mcr.microsoft.com/devcontainers/base:bookworm # mise(ツールバージョン管理)のセットアップ RUN apt-get update \ &&
apt-get -y --no-install-recommends install \ sudo curl git postgresql-client ca-certificates build-essential \ && rm -rf /var/lib/apt/lists/* SHELL ["/bin/bash", "-o", "pipefail", "-c"] ENV MISE_DATA_DIR="/root/.mise" ENV MISE_CONFIG_DIR="/root/.mise" ENV MISE_CACHE_DIR="/root/.mise/cache" ENV MISE_INSTALL_PATH="/usr/local/bin/mise" ENV PATH="/root/.mise/shims:$PATH" # miseのインストール RUN gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys 0x7413A06D \ && curl https://mise.jdx.dev/install.sh.sig | gpg --decrypt > install.sh \ && sh ./install.sh USER root 24
compose.yml(共通設定) services: postgres: image: postgres:15-alpine environment: POSTGRES_DB: myapp POSTGRES_USER: myapp
POSTGRES_PASSWORD: password volumes: - postgres-data:/var/lib/postgresql/data backend: build: dockerfile: Dockerfile.local volumes: - .:/app - mise:/root/.mise - backend-node-modules:/app/backend/node_modules environment: DATABASE_URL: postgresql://myapp:password@postgres:5432/myapp working_dir: /app/backend command: bash -c "mise trust -a && mise install --yes && pnpm install && pnpm dev" frontend: build: dockerfile: Dockerfile.local volumes: - .:/app - mise:/root/.mise - frontend-node-modules:/app/frontend/node_modules working_dir: /app/frontend command: bash -c "mise trust -a && mise install --yes && pnpm install && pnpm dev" volumes: postgres-data: mise: backend-node-modules: 25
.devcontainer/frontend/devcontainer.json { "name": "frontend", "dockerComposeFile": [ "../../compose.yml", "compose.yml" ], "service":
"frontend", "workspaceFolder": "/app/frontend", "remoteUser": "root", "customizations": { "vscode": { "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode" ], "settings": { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode" } } }, "forwardPorts": [5173] } 26
.devcontainer/frontend/compose.yml(オーバー ライド) services: frontend: command: sleep infinity なぜ sleep infinity
か: ルートの compose.yml では pnpm dev が実行される DevContainer では、VS Code 接続後にターミナルでコマンドを実行したい sleep infinity でコンテナを待機状態に保つ 27
設定の流れ 1. VS Code で「Open Folder in Container」を選択 2. .devcontainer/frontend
を選択 3. DevContainer が以下を実行: - compose.yml を読み込む - .devcontainer/frontend/compose.yml でオーバーライド - frontend サービスに接続 - /app/frontend をワークスペースとして開く - 指定された拡張機能をインストール 28
カスタマイズ: ワークスペースをルートにしたい 場合 パターン2 をベースに、ワークスペースだけルートにすることも可能 { "workspaceFolder": "/app", // ルートを開く
"service": "frontend" // 接続先は frontend コンテナ } これにより: ファイルツリーには全ファイルが表示 拡張機能は frontend 用のみインストール Git 操作もコンテナ内で可能 29
まとめ パターン1(単一)がおすすめ 1人開発 少人数で全体を触る 同じ言語スタック パターン2(サービス別)がおすすめ チーム開発 担当が分かれている 言語が大きく異なる 正解は1つではない。チームとプロジェクトに合わせて選択する
30
ありがとうございました