Dock Stay
開発コンテナを定義する - devcontainer.json の使い方・オプション・サンプル

開発コンテナを定義する - devcontainer.json

`devcontainer.json` は Dev Container の設定を記述する中心ファイル。ベースイメージ、ポート転送、VS Code 拡張、起動後コマンドなどをまとめて指定する。

概念図

devcontainer.json diagram

構文

bash
.devcontainer/devcontainer.json

実例

最小構成。公式ベースイメージに拡張と postCreate を重ねる。

bash
{
  "name": "Node 20 app",
  "image": "mcr.microsoft.com/devcontainers/javascript-node:20",
  "forwardPorts": [3000],
  "postCreateCommand": "npm install",
  "customizations": {
    "vscode": {
      "extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"],
      "settings": { "editor.formatOnSave": true }
    }
  }
}

自前 Dockerfile + features でランタイムを重ねるパターン。

bash
{
  "name": "Python + Postgres",
  "build": { "dockerfile": "Dockerfile" },
  "features": {
    "ghcr.io/devcontainers/features/python:1": { "version": "3.12" },
    "ghcr.io/devcontainers/features/common-utils:2": {}
  },
  "forwardPorts": [5432, 8000],
  "remoteUser": "vscode",
  "postCreateCommand": "pip install -r requirements.txt"
}

最低限押さえるキー

キー 役割
name VS Code 上での表示名
image ベースとなる OCI イメージ(mcr.microsoft.com/devcontainers/* が王道)
build.dockerfile 自前の Dockerfile を使う場合のパス
features 公式 / サードパーティの追加機能を重ねる
forwardPorts ホストから見えるように転送するポート
postCreateCommand 1 回目のビルド直後に走らせる初期化(npm install など)
postStartCommand コンテナ起動ごとに走らせるコマンド
customizations.vscode.extensions 自動インストールする VS Code 拡張
remoteUser コンテナ内で使うユーザー(vscode / node 等)

imagebuild はどちらか片方を指定します。

小規模なら image、Dockerfile を書きたくなるほど依存がある場合は build を選びます。

配置場所と複数プロファイル

基本は /.devcontainer/devcontainer.json 1 本ですが、/.devcontainer/<profile>/devcontainer.json のようにサブフォルダを切って複数プロファイルを持つこともできます。

VS Code はリポジトリを開いたときに使いたい設定を選択させてくれます。

例として「GPU あり用」「CPU のみ軽量用」「E2E テスト用」を分けて持ち、普段は軽量を使いつつ必要なときだけ GPU 版で開く、という運用ができます。

よく使う追加キー(mount / env / lifecycle)

  • mounts: ホストのパスやボリュームを明示的にマウントする(例: Docker ソケット、dotfiles、node_modules を名前付きボリュームに逃がす)
  • containerEnv / remoteEnv: コンテナに渡す環境変数。前者はコンテナ起動時、後者は VS Code のリモートセッションに反映
  • onCreateCommand: コンテナ作成時に一度だけ実行(postCreate より前)
  • updateContentCommand: ソースツリーが更新された後に走らせる(CI 向け)
  • waitFor: 他のライフサイクルコマンドの完了を待つ指定

node_modules のような大量ファイルをホストに bind mount すると遅くなる場合は、mounts で名前付きボリュームに逃がすテクニックが有効です。

"mounts": [
  "source=myproj-node_modules,target=/workspaces/myproj/node_modules,type=volume"
]

よくある落とし穴

  • postCreateCommand が重すぎる: 5 分超えるとリビルドのたびに待ち時間が積み重なる。依存の初回セットアップは Dockerfile 側に寄せ、postCreateCommand では最小限に留める
  • forwardPorts を書き忘れる: 3000 で待ち受けるサーバーを立ち上げてもブラウザで開けない → VS Code が自動検出してくれる場合もあるが、明示した方が挙動が安定する
  • remoteUser を指定しない: ルートで動いてしまい、bind mount 経由でホストに root:root のファイルが生成される事故が起きやすい
  • 拡張の入れすぎ: extensions に 50 個並べるとコンテナ起動のたびにインストールされる。個人用拡張は dotfiles で運用する方が軽い

関連トピック