GitHub Codespaces の devcontainer.json で環境構築を自動化し Copilot の機密ファイル除外を設定してみた
製造ビジネステクノロジー部の小林です。
前回の記事では、GitHub Codespaces の組織設定・ポリシーを一から設定しました。Codespace の起動はできましたが、devcontainer.json がない状態ではデフォルトの Ubuntu イメージがそのまま使われるため、ビルドエラーが発生したり、チームで統一したい設定が反映されていませんでした。
今回は devcontainer.json を使って、開発環境のカスタマイズとセキュリティ設定を行っていきます。
devcontainer.json とは
devcontainer.json は、Dev Container 仕様に基づいた設定ファイルです。リポジトリの .devcontainer/devcontainer.json に配置すると、Codespace 作成時に自動的に環境が構成されます。
VS Code Dev Containers 拡張、GitHub Codespaces など複数のツールで利用される共通仕様です。
基本的な構成
今回作成する devcontainer.json の完成形です。以降のセクションで各プロパティを詳しく説明します。
{
"name": "My Project",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
// Dockerfile を書かずにツールを追加できる仕組み
"features": {
// Node.js
"ghcr.io/devcontainers/features/node:1": { "version": "24" },
// AWS CDK
"ghcr.io/devcontainers-contrib/features/aws-cdk:2": {},
// AWS CLI
"ghcr.io/devcontainers/features/aws-cli:1": {},
// GitHub CLI(gh コマンド。base:ubuntu イメージには含まれていないため追加)
"ghcr.io/devcontainers/features/github-cli:1": {}
},
// VS Code 拡張機能と設定
"customizations": {
"vscode": {
"extensions": [
"GitHub.copilot-chat",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
],
"settings": {
// 機密ファイルを Copilot の補完対象から除外
"github.copilot.enable": {
"*": true,
"dotenv": false,
"plaintext": false
// .pem, .key などはplaintextとして扱われる
}
}
}
},
// ポートフォワーディング
"forwardPorts": [3000, 8080],
// マシンスペックの最小要件
"hostRequirements": {
"cpus": 2,
"memory": "8gb",
"storage": "32gb"
},
// コンテナ作成後に実行されるコマンド
"postCreateCommand": "npm install"
}
image — ベースイメージの指定
ベースとなる Docker イメージを指定します。ここでは Microsoft 公式の Dev Container イメージを使っています。
// Ubuntu ベース
"image": "mcr.microsoft.com/devcontainers/base:ubuntu"
組織ポリシーの Base images 制約を設定した場合、ここで指定するイメージは、ポリシーで許可されている必要があります。
例えば mcr.microsoft.com/devcontainers/* のみ許可するポリシーを設定していた場合、Docker Hub の公式イメージ(docker.io/library/node など)は使えません。
features — ツールやランタイムの追加
Features は、Dockerfile を書かずに Node.js や AWS CLI などのツールを追加できる仕組みです。
"features": {
// Node.js
"ghcr.io/devcontainers/features/node:1": { "version": "24" },
// AWS CDK
"ghcr.io/devcontainers-contrib/features/aws-cdk:2": {},
// AWS CLI
"ghcr.io/devcontainers/features/aws-cli:1": {},
// GitHub CLI(gh コマンド。base:ubuntu イメージには含まれていないため追加)
"ghcr.io/devcontainers/features/github-cli:1": {}
},
aws-cdk:2 や node:1 の :2 :1 は Feature 自体のメジャーバージョンです。Feature のバージョンはセマンティックバージョニングに従っており、:2 と書くと「メジャーバージョン 2 の最新」が使われます。
メジャーバージョンが上がると破壊的変更がある可能性があるため、:2 のようにメジャーバージョンだけ固定しておくことをおすすめします。
customizations — 拡張機能と設定の統一
VS Code の拡張機能や設定をチームで統一できます。拡張機能のプリインストールに加えて、Copilot のセキュリティ設定もここで行います。
拡張機能のプリインストール
"customizations": {
"vscode": {
"extensions": [
"GitHub.copilot-chat",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
}
ここに記載した拡張機能は、Codespace 作成時に自動でインストールされます。チームで統一すべきリンターやフォーマッターはここに含めます。
なお、devcontainer.json の extensions は起動時のプリインストールリストであり、ユーザーが追加で他の拡張機能をインストールすることは防げません。
ただし、組織全体で拡張機能の使用を制限したい場合は、VS Code のエンタープライズポリシー(AllowedExtensions)をデバイス管理ソリューション経由で展開することで実現できます。
Copilot のセキュリティ設定
"customizations": {
"vscode": {
"settings": {
// 機密ファイルを Copilot の補完対象から除外
"github.copilot.enable": {
"*": true,
".env": false,
"*.pem": false,
"*.key": false
}
}
}
}
github.copilot.enable
github.copilot.enable のキーにはファイル拡張子ではなく、VS Code の言語 ID を指定します。.env ファイルの言語 ID は dotenv(VS Code のステータスバーで確認可能)、.pem や .key などはプレーンテキストとして扱われるため plaintext を指定します。
これにより、機密ファイルを Copilot の補完対象から除外し、ファイルの内容が Copilot に送信されるのを防ぎます。
なお、この設定はあくまでデフォルト値であり、ユーザーが Copilot のステータスパネルから手動で有効に切り替えることは防げません。Codespace をリビルドすれば devcontainer.json の設定に戻ります。
ライフサイクルコマンド
コンテナのライフサイクルに応じて、様々なタイミングでコマンドを実行できます。
{
// コンテナ作成時に 1 回だけ実行(依存関係のインストールなど)
"postCreateCommand": "npm install",
// コンテナ起動時に毎回実行
"postStartCommand": "npm run dev",
// VS Code がコンテナに接続した後に実行
"postAttachCommand": "echo 'Ready to code!'"
}
前回の記事で npm run build が失敗していたのは、npm install が事前に実行されていなかったためでした。postCreateCommand に npm install を指定しておけば、Codespace 作成時に自動で依存関係がインストールされ、このエラーは発生しなくなります。
forwardPorts — ポートフォワーディング
Codespace 内で開発サーバーを起動すると、そのサーバーはコンテナ内のポート(例:localhost:3000)で動作します。しかし、コンテナ内のポートはそのままではブラウザからアクセスできません。ポートフォワーディングとは、コンテナ内のポートを自分のブラウザからアクセスできるようにする仕組みです。
forwardPorts を指定すると、Codespace 起動時に自動でフォワーディングが設定されます。
"forwardPorts": [3000, 8080]
この設定がない場合でも、ターミナルでサーバーを起動すれば VS Code が自動検出してフォワーディングを提案してくれますが、forwardPorts に書いておけば毎回手動で設定する手間がなくなります。
Organizations で設定した Port privacy settings のポリシーは、ここでフォワーディングされたポートにも適用されます。例えば「Org」のみ許可するポリシーを設定していた場合、フォワーディングされたポートへのアクセスは組織メンバーに限定されます。
hostRequirements — マシンスペックの最小要件
プロジェクトに必要なマシンスペックの最小要件を指定できます。
"hostRequirements": {
"cpus": 2,
"memory": "8gb",
"storage": "32gb"
}
Codespace 作成時の選択肢は、hostRequirements の最小要件と組織ポリシーの Machine types 制約の両方で絞り込まれます。
なお、検証では "cpus": 4 を指定したところ、ポリシーで 2-core のみ許可しているにもかかわらず 4 コアの Codespace が作成できました。公式ドキュメントの記述とは異なる動作のため、今後の仕様変更やバグ修正の可能性があります。
Dockerfile との併用
image だけでは対応できないケース
image + features の組み合わせで多くのケースはカバーできますが、以下のような場合は Dockerfile が必要になります。
- Features に存在しないツールやライブラリをインストールしたい — 例えば特定バージョンのネイティブライブラリや、apt で直接インストールするパッケージ
- インストール順序を制御したい — Features 同士の実行順序は保証されないが、Dockerfile なら
RUNの順序通りに実行される - ベースイメージの上にカスタムレイヤーを重ねたい — 組織で共通の設定やセキュリティパッチを適用済みのイメージを作る場合
- ビルド時の最適化をしたい — レイヤーキャッシュを活用して、変更が少ない部分のビルド時間を短縮する
基本的な使い方
image の代わりに build プロパティで Dockerfile を参照します。以下は例です。
{
"name": "Custom Environment",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
// features は Dockerfile と併用可能
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"postCreateCommand": "npm install"
}
context は Docker ファイルを参照するルートディレクトリを指定します。".." にすると、リポジトリのルートディレクトリがコンテキストになり、Dockerfile から COPY でリポジトリ内のファイルを参照できます。
image と Dockerfile の使い分け
| 方法 | 使うとき |
|---|---|
image + features |
公式イメージ + Features の組み合わせで足りる場合。シンプルで管理しやすい |
build + Dockerfile |
apt パッケージの追加、特定バージョンのツール、カスタム設定ファイルの組み込みなどが必要な場合 |
なお、Dockerfile を使う場合でも FROM で指定するベースイメージは組織ポリシーの Base images 制約に従う必要があります。
動作確認
実際に devcontainer.json を配置して Codespace を作成し、各設定が反映されているか確認していきます。
Codespace の起動
devcontainer.json をリポジトリの .devcontainer/ に配置してコミット・プッシュします。
続いて Codespace を新規作成します。

作成できました。

Node.js のバージョン
ターミナルで node -v を実行し、Node.js 24 がインストールされていることを確認します。

Node.js の v24.16.0 であることが確認できました。
npm install の自動実行
postCreateCommand に指定した npm install が自動で実行され、node_modules が作成されていることを確認します。

前回のような tsc が見つからないエラーが解消されているはずです。
npm run build の成功
npm run build(tsc)が正常に実行できることを確認します。

エラーなく正常に build が成功しました。
拡張機能のプリインストール
devcontainer.json で指定した拡張機能(GitHub Copilot、ESLint、Prettier)が自動でインストールされていることを確認します。

拡張機能パネルの「インストール済み」には、ESLint と Prettier が表示されていました。
一方、GitHub Copilot Chat は「インストール済み」一覧には表示されませんが、検索すると既にインストール済みになっています。

これは Copilot Chat が VS Code 本体にネイティブ統合されているためです。Codespaces は VS Code ベースの環境なので、devcontainer.json で指定しなくても最初から含まれています。
また、devcontainer.json の extensions で指定していない AWS Toolkit もインストールされていました。これは aws-cli feature の devcontainer-feature.json に推奨拡張機能として AmazonWebServices.aws-toolkit-vscode が定義されているためです。Features は関連する VS Code 拡張機能を自動的にインストールする仕組みを持っています。
Japanese Language Pack については、原因が特定できていません。
機密ファイルの Copilot 除外
devcontainer.json で .env ファイルを Copilot の補完対象から除外する設定をしました。.ts ファイルを開くと、Copilot のインライン提案が「有効」と表示されます。

一方、.env ファイルを開くと、インライン提案が「無効」に切り替わり、Dotenv のゴーストテキストの候補もオフになっていることが確認できました。github.copilot.enable の "dotenv": false が正しく反映されています。

AWS CLI と GitHub CLI
Features で追加した AWS CLI と GitHub CLI がインストールされていることを確認します。

両方ともインストールされていました。
ポートフォワーディング
forwardPorts で指定したポート 3000 と 8080 が自動でフォワーディングされていることを確認します。VS Code の「ポート」タブを開くと、指定したポートが一覧に表示されています。

表示範囲が「Private」になっており、Codespace 作成者本人のみがアクセスできる状態です。前回の記事で設定した Port privacy settings のポリシーで「Org」のみ許可していた場合、ここから「Org」に変更することはできますが、「Public」には変更できません。
hostRequirements
hostRequirements で指定したマシンスペックの最小要件が反映されているか確認します。ターミナルで nproc コマンドを実行すると、利用可能なCPU数が表示されます。

"cpus": 2 に対して nproc の結果が 2 となりました。nproc は Linux で利用可能なプロセッサ数を表示するコマンドです。
設定変更後のリビルド
devcontainer.json を変更した場合、既存の Codespace に反映するにはコンテナのリビルドが必要です。
VS Code 左下にある「Codespaces: congenial enigma」をクリックし、「Rebuild Container」を選択します。

新規の Codespace 作成時には自動的に最新の設定が適用されます。
まとめ
今回は devcontainer.json を使った開発環境のカスタマイズについてまとめました。
前回の組織設定・ポリシーと今回の devcontainer.json を組み合わせることで、以下のようなセキュリティ統制が実現できます。
| レイヤー | 対応 |
|---|---|
| 組織ポリシー(前回) | マシンタイプ制限、ベースイメージ制限、idle timeout、retention period |
| devcontainer.json(今回) | 拡張機能の統一、Copilot セキュリティ設定、環境の自動構築 |
一方で、今回の検証を通じて devcontainer.json だけでは制御しきれない領域も見えてきました。
- Agent Mode のタスク自動承認の制御 — VS Code のエンタープライズポリシー(ChatToolsEligibleForAutoApproval)で設定が必要
- 拡張機能のインストール制限 — VS Code のエンタープライズポリシー(AllowedExtensions)で設定が必要
- 拡張機能の自動更新の無効化 — devcontainer.json からは反映されず、ユーザー設定またはエンタープライズポリシーでの対応が必要
devcontainer.json をリポジトリに含めておけば、チームメンバーが Codespace を作成するだけで、セキュリティ設定込みの統一された開発環境が自動で立ち上がります。
この記事がどなたかの参考になれば幸いです。






