devcontainer で開発環境を配る
VS Code Dev Containers / GitHub Codespaces の仕組みを使い、リポジトリに `devcontainer.json` を置くだけで同じ開発環境を全員に配る方法をまとめます。
devcontainer とは
devcontainer は、開発環境そのものをコンテナで配布する仕組みです。
リポジトリに .devcontainer/devcontainer.json を置き、必要なツール・拡張機能・初期化スクリプトを宣言しておくと、次のような環境で同じ開発環境が自動で立ち上がります。
- VS Code の拡張機能 "Dev Containers"
- GitHub Codespaces(クラウド上の devcontainer)
- JetBrains Gateway
devcontainerCLI(npm install -g @devcontainers/cli)
「M1 Mac でだけ動かない」「Node.js のバージョンを合わせるのに半日かかる」といった、オンボーディングの摩擦をほぼ消せるのが価値です。
最小の devcontainer.json
最小構成は次の通り。
ベースイメージを指定するだけで動きます。
// .devcontainer/devcontainer.json
{
"name": "my-app dev",
"image": "mcr.microsoft.com/devcontainers/javascript-node:20",
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
},
"postCreateCommand": "npm install",
"forwardPorts": [3000]
}
VS Code で「Reopen in Container」を選ぶと、このイメージが pull されてコンテナが起動し、指定した拡張機能が自動インストール、npm install が実行され、ポート 3000 がホストに転送されます。
features で道具を追加する
features は「よく使うツールを 1 行で足せる」ミニパッケージ集です。
Docker-in-Docker、AWS CLI、Terraform、gh など、開発で必要になりがちなものが揃っています。
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node:1": { "version": "20" },
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/aws-cli:1": {}
}
}
自前で Dockerfile を書かなくても、ベースイメージ + features だけで実用的な環境が組めます。
プロジェクト固有の依存は postCreateCommand に書くか、dockerFile を別に書いて組み合わせます。
Compose と組み合わせる
DB や他のサービスが必要なプロジェクトでは、devcontainer が Compose の 1 サービスとして動くよう設定できます。
{
"name": "my-app dev",
"dockerComposeFile": ["../compose.yaml", "compose.dev.yaml"],
"service": "web",
"workspaceFolder": "/app",
"shutdownAction": "stopCompose"
}
compose.yaml に web + db を書き、devcontainer は web サービスにアタッチ。
この形にすると、普段は docker compose up で本番に近い構成を動かしつつ、VS Code からはそのコンテナの中で開発ができるという両立ができます。
Codespaces と devcontainer CLI
GitHub Codespaces は、GitHub 上のリポジトリから 1 クリックで devcontainer をクラウド(仮想マシン)上に立ち上げる仕組みです。
.devcontainer/devcontainer.json がそのまま使われるので、ローカルの VS Code と完全に同じ環境がブラウザや VS Code Web 版で動きます。
CI や自動化で devcontainer と同じ環境を使いたいときは devcontainer CLI が便利です。
# コンテナを起動(存在しなければビルド)
devcontainer up --workspace-folder .
# コンテナ内でコマンドを実行
devcontainer exec --workspace-folder . npm test
GitHub Actions の devcontainers/ci アクションと組み合わせると、開発と CI が文字どおり同じイメージを使う状態を作れます。
つまずきポイント
- 初回起動が重い: ベースイメージの pull、features のインストール、
postCreateCommandが順に走る。初回は数分かかることも。prebuilds(Codespaces)やdevcontainer buildでイメージを事前に焼いておくと速い - macOS で bind mount が遅い: VS Code の Dev Containers では内部的に volume mount を使っているのであまり問題にならないが、Compose 経由の構成では
:cachedオプションや Mutagen の利用を検討 - 権限問題: コンテナ内の既定ユーザーが
vscodeやnodeなどの非 root の場合、ホストの bind mount したファイルの UID と合わず書き込めないことがある。remoteUserの設定と、UID を合わせるエントリポイントでの調整を行う - 拡張機能が多すぎる: チーム用のリストは必要最低限にし、個人設定は
settings.jsonの Remote ではなくユーザー設定側に置く onCreateCommand/postCreateCommand/postStartCommandの使い分け: 1 度だけ必要なセットアップはpostCreateCommand、再起動のたびに実行したい処理はpostStartCommand
