取り組みの背景 — 「自分のマシンでは動くのに」を根絶する
AI 駆動の開発において、環境の再現性は生産性に直結します。Antigravity のエージェントが生成するコードは、Node.js のバージョン、Python のパッケージ、システムライブラリの有無など、実行環境に強く依存します。チームメンバー間で「自分のマシンでは動くのに、相手の環境では動かない」という問題は、開発速度を著しく低下させます。
Dev Containers と Docker を活用して、Antigravity の AI 開発環境を完全に再現可能にする方法を順を追って整理していきます。devcontainer.json の設計パターンからマルチステージビルド、CI/CD との統合まで、本番運用に耐える構成を段階的に構築していきます。
対象読者: Docker の基本操作(docker build、docker run)を理解しており、Antigravity でのチーム開発を効率化したいエンジニア
前提環境:
- Docker Desktop 4.x 以上
- Antigravity IDE(最新版)
- Node.js 22 LTS / Python 3.12 以上(コンテナ内)
Dev Containers とは — IDE とコンテナの統合アーキテクチャ
Dev Containers は、開発環境をコンテナとして定義・共有するためのオープンな仕様です。プロジェクトのルートに .devcontainer/devcontainer.json を配置することで、IDE が自動的にコンテナを起動し、その中で開発を行います。
従来の開発環境構築では、README に「Node.js 22 をインストールしてください」「Python 3.12 が必要です」と書かれていても、実際のバージョンやシステムライブラリの違いで問題が発生していましました。Dev Containers はこの問題を根本的に解決します。
Antigravity は Dev Containers をネイティブでサポートしており、.devcontainer/devcontainer.json を検出すると自動的にコンテナ内で AI エージェントが動作します。これにより、エージェントが生成したコードは常にコンテナ内の統一された環境で実行・検証されます。
Dev Containers の構成要素
Dev Containers の構成は主に3つの要素で成り立っています。まず devcontainer.json はコンテナの設定・拡張機能・ポートフォワーディングなどを定義する中核ファイルです。次に Dockerfile(または docker-compose.yml)でベースイメージ・パッケージ・システム設定を定義します。そして Features は再利用可能な開発ツールのパッケージで、Node.js や Python、Docker-in-Docker などを簡単に追加できます。
基本構成 — Antigravity 向け devcontainer.json の設計
まず、Antigravity での開発に最適化された基本的な devcontainer.json を設計します。
// .devcontainer/devcontainer.json
{
"name": "Antigravity AI Dev",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
"NODE_VERSION": "22",
"PYTHON_VERSION": "3.12"
}
},
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
},
"customizations": {
"antigravity": {
"extensions": [],
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh"
}
}
},
"forwardPorts": [3000, 5432, 6379],
"postCreateCommand": "npm install && npm run setup",
"postStartCommand": "echo '✅ Dev Container ready'",
"remoteUser": "node"
}このファイルでは、build セクションでカスタム Dockerfile を使用し、Node.js と Python のバージョンをビルド引数で制御しています。features で Git、GitHub CLI、Docker-in-Docker を追加し、forwardPorts で開発サーバーやデータベースのポートを自動転送します。
カスタム Dockerfile — マルチステージビルドで軽量化
基本的な Dev Container は Feature だけで構成できますが、本番に近い環境を再現するにはカスタム Dockerfile が必要です。マルチステージビルドで不要なレイヤーを排除し、ビルド時間とイメージサイズを最適化します。
# .devcontainer/Dockerfile
# ============================================
# Stage 1: ベースイメージ + システム依存関係
# ============================================
ARG NODE_VERSION=22
FROM mcr.microsoft.com/devcontainers/javascript-node:${NODE_VERSION} AS base
ARG PYTHON_VERSION=3.12
RUN apt-get update && apt-get install -y --no-install-recommends \
python${PYTHON_VERSION} \
python${PYTHON_VERSION}-venv \
python3-pip \
build-essential \
libcairo2-dev \
libpango1.0-dev \
libjpeg-dev \
libgif-dev \
librsvg2-dev \
&& rm -rf /var/lib/apt/lists/*
# Python の仮想環境を作成
RUN python${PYTHON_VERSION} -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# ============================================
# Stage 2: 依存関係のインストール
# ============================================
FROM base AS deps
WORKDIR /workspace
COPY package.json package-lock.json ./
RUN npm ci --prefer-offline
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# ============================================
# Stage 3: 開発環境(最終イメージ)
# ============================================
FROM base AS development
# deps ステージから node_modules をコピー
COPY --from=deps /workspace/node_modules /workspace/node_modules
COPY --from=deps /opt/venv /opt/venv
# zsh + oh-my-zsh のセットアップ
RUN apt-get update && apt-get install -y zsh \
&& sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended \
&& rm -rf /var/lib/apt/lists/*
# 開発用の便利ツール
RUN npm install -g \
typescript \
tsx \
@biomejs/biome \
turbo
WORKDIR /workspace
ENV NODE_ENV=developmentこのマルチステージビルドのポイントは3つあります。Stage 1 でシステム依存関係を固定し、--no-install-recommends で不要パッケージを排除します。Stage 2 で package.json と requirements.txt のみをコピーしてキャッシュレイヤーを最大化します。Stage 3 では deps ステージから成果物だけをコピーし、開発ツールを追加します。
この構成により、ソースコードの変更時には Stage 3 だけが再ビルドされ、依存関係のインストールはキャッシュが効くため、ビルド時間は初回以降大幅に短縮されます。
環境変数とシークレットの安全な管理
開発環境では API キーやデータベース接続情報などのシークレットを扱いますが、これらを devcontainer.json や Dockerfile にハードコードしてはいけません。
// .devcontainer/devcontainer.json(抜粋)
{
"containerEnv": {
"NODE_ENV": "development",
"LOG_LEVEL": "debug",
"API_BASE_URL": "http://localhost:3000"
},
"secrets": {
"DATABASE_URL": {
"description": "PostgreSQL connection string",
"documentationUrl": "https://wiki.example.com/db-setup"
},
"STRIPE_SECRET_KEY": {
"description": "Stripe API secret key (test mode)"
}
}
}containerEnv には機密性のない環境変数を直接記述し、secrets セクションでは IDE がユーザーに安全な入力を促します。この仕組みにより、シークレットが Git リポジトリにコミットされるリスクを排除できます。
もう一つの実践的なパターンとして、.env.example ファイルをリポジトリに含め、postCreateCommand でローカルの .env にコピーする方法があります。
{
"postCreateCommand": "cp -n .env.example .env && npm install"
}-n フラグにより、既存の .env を上書きしないため、個人の設定が保護されます。
Antigravity エージェントとの統合 — AGENTS.md とコンテナの連携
Antigravity のエージェントは、Dev Container 内で動作する際にコンテナの環境を自動検出します。AGENTS.md で Dev Container 固有の指示を追加することで、エージェントの振る舞いを最適化できます。
<!-- AGENTS.md -->
# 開発環境
このプロジェクトは Dev Container で動作します。
## 環境制約
- Node.js 22 LTS(コンテナ内にプリインストール済み)
- Python 3.12(/opt/venv にインストール済み)
- PostgreSQL はポート 5432 でアクセス可能(docker-compose で起動)
- Redis はポート 6379 でアクセス可能
## コマンド実行ルール
- `npm` コマンドは /workspace ディレクトリで実行すること
- Python スクリプトは仮想環境(/opt/venv)内で実行すること
- データベースマイグレーションは `npm run db:migrate` を使用すること
- テストは `npm run test` で全テストスイートを実行すること
## 禁止事項
- グローバルに npm パッケージをインストールしないこと(node_modules のみ使用)
- システムパッケージを apt で追加しないこと(Dockerfile を変更すること)
- .env ファイルを直接編集しないこと(.env.local を使用すること)この AGENTS.md により、Antigravity のエージェントはコンテナ環境の制約を理解した上でコードを生成・実行します。たとえば、Python のパッケージを追加する場合、エージェントは pip install ではなく requirements.txt への追記と Dockerfile の再ビルドを提案するようになります。
Docker Compose による複合サービス構成
実際のプロジェクトでは、アプリケーションサーバーだけでなくデータベース、キャッシュ、メッセージキューなど複数のサービスが必要です。docker-compose.yml を Dev Container と統合して、完全な開発スタックを一度に起動します。
# docker-compose.yml
services:
app:
build:
context: .
dockerfile: .devcontainer/Dockerfile
target: development
volumes:
- .:/workspace:cached
- node_modules:/workspace/node_modules
ports:
- "3000:3000"
- "9229:9229" # Node.js デバッグポート
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
environment:
DATABASE_URL: postgres://dev:devpass@postgres:5432/appdb
REDIS_URL: redis://redis:6379
NODE_ENV: development
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: dev
POSTGRES_PASSWORD: devpass
POSTGRES_DB: appdb
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/init-db.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dev"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/var/lib/redis/data
volumes:
node_modules:
postgres_data:
redis_data:devcontainer.json から Docker Compose を参照する場合の設定は以下の通りです。
// .devcontainer/devcontainer.json(Docker Compose 版)
{
"name": "Antigravity Full Stack",
"dockerComposeFile": ["../docker-compose.yml"],
"service": "app",
"workspaceFolder": "/workspace",
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"forwardPorts": [3000, 5432, 6379],
"postCreateCommand": "npm install && npm run db:migrate",
"remoteUser": "node"
}ここで重要なのは volumes の設計です。node_modules を名前付きボリュームにすることで、ホストマシンとコンテナ間のファイルシステムの違い(特に macOS のファイル監視のオーバーヘッド)を回避し、npm install の速度を大幅に改善できます。
パフォーマンス最適化 — ビルド時間とI/Oの改善
Dev Container の開発体験を左右する最大の要因はパフォーマンスです。以下の最適化テクニックを適用することで、コンテナの起動時間とファイル I/O のパフォーマンスを大幅に改善できます。
ボリュームマウントの最適化
macOS と Windows では、ホストとコンテナ間のファイル同期がボトルネックになります。cached マウントオプションを活用し、重いディレクトリは名前付きボリュームに分離します。
{
"mounts": [
"source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached",
"source=antigravity-node-modules,target=/workspace/node_modules,type=volume",
"source=antigravity-next-cache,target=/workspace/.next,type=volume"
]
}node_modules と .next(Next.js のビルドキャッシュ)をボリュームに分離することで、macOS の場合にファイル監視のパフォーマンスが最大10倍改善されることがあります。
BuildKit キャッシュの活用
Dockerfile で BuildKit のキャッシュマウントを使うと、npm install や pip install の再実行時にダウンロード済みパッケージを再利用できます。
# BuildKit キャッシュを活用した高速インストール
RUN --mount=type=cache,target=/root/.npm \
npm ci --prefer-offline
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir -r requirements.txtプレビルドで初回起動を高速化
GitHub Codespaces や Antigravity Cloud を使用する場合、プレビルドを設定することで初回のコンテナ起動時間をほぼゼロにできます。
// .devcontainer/devcontainer.json
{
"updateContentCommand": "npm ci && npm run build",
"waitFor": "updateContentCommand"
}updateContentCommand はプレビルド時に実行され、postCreateCommand よりも前にキャッシュされます。これにより、新しいブランチの作成時やコンテナの再構築時に依存関係のインストールをスキップできます。
CI/CD との統合 — 開発と本番の環境差を排除する
Dev Container で定義した環境を CI/CD パイプラインでも使用することで、「CIでは通るのにローカルでは失敗する」問題を根絶できます。
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Dev Container
uses: devcontainers/ci@v0.3
with:
runCmd: |
npm run lint
npm run typecheck
npm run test -- --coverage
npm run build
- name: Upload coverage
uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage/devcontainers/ci アクションは、.devcontainer/devcontainer.json を読み取ってコンテナを構築し、その中でコマンドを実行します。これにより、ローカル開発・CI・ステージング環境のすべてが同一のコンテナ定義に基づくことが保証されます。
GitHub Actions のキャッシュ戦略
CI でのビルド時間を短縮するために、Docker レイヤーキャッシュを活用します。
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ hashFiles('.devcontainer/**') }}
restore-keys: |
${{ runner.os }}-buildx-チーム開発でのベストプラクティス
Dev Container をチームで運用する際には、以下のルールを設けることで環境の統一性を維持できます。
1. Dockerfile の変更はPRレビュー必須
CODEOWNERS ファイルで Dev Container 関連のファイルにレビュー必須のルールを設定します。
# .github/CODEOWNERS
.devcontainer/ @team-lead @devops
Dockerfile @team-lead @devops
docker-compose.yml @team-lead @devops
2. 環境の差分検出スクリプト
チームメンバーのコンテナ環境が最新かどうかを検証するスクリプトを用意します。
#!/bin/bash
# scripts/verify-env.sh
# コンテナ環境の整合性チェック
echo "🔍 環境検証を開始します..."
# Node.js バージョン
NODE_EXPECTED="v22"
NODE_ACTUAL=$(node -v | cut -d. -f1)
if [ "$NODE_ACTUAL" != "$NODE_EXPECTED" ]; then
echo "❌ Node.js: expected $NODE_EXPECTED, got $NODE_ACTUAL"
exit 1
fi
# Python バージョン
PYTHON_EXPECTED="3.12"
PYTHON_ACTUAL=$(python3 --version | cut -d' ' -f2 | cut -d. -f1,2)
if [ "$PYTHON_ACTUAL" != "$PYTHON_EXPECTED" ]; then
echo "❌ Python: expected $PYTHON_EXPECTED, got $PYTHON_ACTUAL"
exit 1
fi
# 必須コマンドの存在チェック
for cmd in git gh docker npm npx tsx biome; do
if ! command -v $cmd &> /dev/null; then
echo "❌ Missing command: $cmd"
exit 1
fi
done
echo "✅ 環境検証に成功しました"3. 自動更新の通知
Dev Container の定義が変更された場合、チームメンバーに再ビルドを促す仕組みを postStartCommand で実装します。
{
"postStartCommand": "bash .devcontainer/check-rebuild.sh"
}#!/bin/bash
# .devcontainer/check-rebuild.sh
HASH_FILE="/tmp/.devcontainer-hash"
CURRENT_HASH=$(md5sum .devcontainer/Dockerfile .devcontainer/devcontainer.json 2>/dev/null | md5sum | cut -d' ' -f1)
if [ -f "$HASH_FILE" ]; then
STORED_HASH=$(cat "$HASH_FILE")
if [ "$CURRENT_HASH" != "$STORED_HASH" ]; then
echo ""
echo "⚠️ Dev Container の定義が更新されています。"
echo " コンテナの再ビルドを推奨します: Cmd+Shift+P → 'Rebuild Container'"
echo ""
fi
fi
echo "$CURRENT_HASH" > "$HASH_FILE"トラブルシューティング — よくある問題と対処法
Dev Container の運用で遭遇しやすい問題とその解決策をまとめます。
コンテナ起動が遅い場合
原因の多くはボリュームマウントの I/O です。consistency=cached の設定と、node_modules を名前付きボリュームに分離しているか確認してください。それでも遅い場合は、Docker Desktop の設定でメモリとCPUの割り当てを増やします。
ポートフォワーディングが機能しない場合
forwardPorts に指定したポートが他のプロセスで使用されていないか確認します。lsof -i :3000 でポートの使用状況を調べ、競合がある場合はポート番号を変更します。
ファイルの権限問題
ホストとコンテナのユーザー ID が異なると、ファイルの読み書きで権限エラーが発生します。remoteUser を正しく設定し、必要に応じて Dockerfile で chown を実行します。
# ワークスペースの所有権を開発ユーザーに設定
RUN mkdir -p /workspace && chown -R node:node /workspaceまとめ
Dev Containers と Docker を活用することで、Antigravity の AI 開発環境を完全に再現可能にし、チーム全体の生産性を大幅に向上させることができます。devcontainer.json の設計、マルチステージビルドによる軽量化、CI/CD との統合、そしてチーム運用のベストプラクティスを組み合わせることで、「環境差異によるバグ」という開発チーム最大の課題の一つを根絶できます。
まずは基本的な devcontainer.json から始め、プロジェクトの成長に合わせて段階的に構成を充実させていくのがおすすめです。一度構築すれば、新メンバーのオンボーディングは「リポジトリをクローンして Dev Container を起動する」だけで完了します。