🎏

devcontainerでClaude Codeを動かす(Windows)

に公開

はじめに

Claude CodeなどのAI AgentをPC上で動かす場合気になるのが、予期せぬファイルやライブラリの追加や更新、削除です。実際Claude Codeを使う場合でも、可能性としてはあります。
この課題を解決する手段として、隔離されたコンテナの中でClaude Codeを動かす方法があります。
今回は、このやり方をご紹介できればと思います。
OSはWindows11 Pro、DockerではPodmanを使う前提としています。(Docker desktopが使えない状況の方もいると思うので。)

構築するアーキテクチャの図

この記事の内容を実施していくと、下記gif動画のようにVS Code上でコンテナ化されたClaude Codeを使用することができるようになります。

VS Code上でコンテナ化されたClaude Codeを使用している様子

Gitをインストール

下記からダウンロードしてインストールしましょう。インストールすると、WindowsのPowerShellからコマンド「git」が使えるようになるはずです。
https://git-scm.com/downloads

Windows PC上のPowerShell
git --version


「git --version」が実行されることでgitがインストールされていることを確認

VS Codeをインストール

下記サイトからダウンロードしてインストールしましょう。
https://code.visualstudio.com/download

Node.jsをインストール

下記サイトからダウンロードしてインストールしましょう。
https://nodejs.org/ja/download

Podmanをインストール

Podman公式ページからPodmanをダウンロードします。CLI操作中心なので、「Podman CLI for Windows」をダウンロードで良いと思います。
https://podman.io/

ダウンロードしたインストーラを起動します。

今回は、WSLv2を使うやり方をとるので、「Windows Linux Subsystems (WSLv2)」を選択した状態で「Install」ボタンを押下します。

インストールが進んできます。

数分で完了します。「Close」ボタンを押下します。

PowerShellからPodmanがインストールされているか確認しましょう。下記のようにバージョン情報が表示されればOKです。

Windows PC上のPowerShell
podman --version

Podmanの仮想マシンを構築

仮想マシン「claudeVM」を作成します。

Windows PC上のPowerShell
podman machine init claudeVM


仮想マシン「claudeVM」を起動します。

Windows PC上のPowerShell
podman machine start claudeVM


また、このあと下記コマンドを実行しましょう。後続タスクの「devcontainer up」の時に、Default=trueになっている仮想環境上にコンテナが構築されるため。

Windows PC上のPowerShell
podman system connection list
# claudeVMのDefault(既定)がfalseの場合、下記コマンドを実行する
podman system connection default claudeVM

DevContainersをインストール

npmを使ってDevContainersをインストールします。

Windows PC上のPowerShell
npm install -g @devcontainers/cli

Claude CodeをClone

任意のフォルダに移動して、GitHub上にあるClaude CodeをCloneしましょう。

Windows PC上のPowerShell
git clone https://github.com/anthropics/claude-code.git
cd claude-code
ls

Claude Codeの.devcontainerをProjectフォルダにコピー

Claude CodeをCloneしたフォルダにあるフォルダ「.devcontainer」を、Claude Code利用対象フォルダ(Projectフォルダ)にコピーします。フォルダ「.devcontainer」にあるファイル「devcontainer.json」「Dockerfile」「init-firewall.sh」にコンテナの定義情報が記載されています。これはAnthropicが定義したもので、この定義情報を使って構築されたコンテナにはClaude Codeがインストールされたり、フォルダがマウントされた状態になっています。

devcontainerを構築

ここからはVS Codeを起動して、PowerShellのTerminalでコマンドを実行していきます。
VS CodeでClaude Codeを使ってAI開発したいProjectのフォルダを開いたうえで下記コマンドを実行します。

VS CodeのTerminal(PowerShell)
devcontainer up --workspace-folder . --docker-path podman

devcontainer内にアクセス

下記gif動画では、このようなコマンドを実行しています。

VS CodeのTerminal(PowerShell)
# devcontainerのCONTAINER IDを確認する
podman ps
# 上記で確認したCONTAINER IDを使ってdevcontainer内へアクセスする
podman exec -it <上記で確認したCONTAINER ID> zsh 

ただ、このやり方だと手動のコピペが発生して効率的ではないです。実際は下記のようなやり方が良いのでは?と考えています。

VS CodeのTerminal(PowerShell)
# 1. 現在のワークスペースフォルダのパスを取得
$currentFolder = (Get-Location).Path

# 2. そのフォルダのラベルを持つコンテナのIDを検索
# --filter "label=devcontainer.local_folder=$currentFolder" でフィルタリング
# --format "{{.ID}}" でIDのみを出力
$containerId = podman ps --filter "label=devcontainer.local_folder=$currentFolder" --format "{{.ID}}"

# 3. 取得したコンテナIDを使ってpodman execを実行
podman exec -it $containerId zsh

devcontainer内でClaude Codeを起動 + 使う

devcontainer内にアクセスできたので、Claude Codeを起動します。

VS CodeのTerminal(PowerShell) -> devcontainer内
claude

下記gif動画ではこのようなプロンプトを送信しています。

プロンプト
pages/activities/logic-puzzle.htmlがどのような処理になっているか説明してください。

PowerShellのScriptで自動化

Scriptの内容

このPowerShell Scriptは、DevContainerを使った開発環境へのスムーズな移行を自動化するものです。
実行すると、まずPodman仮想マシンが起動しているかを確認し、必要であれば起動します。次に、現在のプロジェクトに対応するDevContainerを立ち上げます。コンテナが起動したら、その固有のIDを自動で取得し、そのコンテナ内部へ接続。そして、指定されたclaudeコマンドを実行後、すぐにインタラクティブなzshシェルを立ち上げます。
これにより、Script一つで開発環境の準備から、コンテナ内での初期コマンド実行、そして操作可能なシェルプロンプトの表示までが一気に完了し、すぐに開発作業に取りかかれるようになります。

Start-ClaudeEnvironment.ps1
# スクリプトの開始を通知
Write-Host "--- DevContainer 起動・接続スクリプト ---"

# --- Step 1: Podman machine の起動 ---
Write-Host "Podman machine 'claudeVM' を起動しています..."
try {
    # Podman machine start はすでに起動していれば何もしません
    # -q オプションで出力を抑制
    podman machine start claudeVM -q
    Write-Host "Podman machine 起動済みまたは起動しました。"
} catch {
    Write-Error "Podman machine の起動に失敗しました: $($_.Exception.Message)"
    exit 1 # エラーが発生したらスクリプトを終了
}

# --- Step 2: デフォルトコネクションの設定 ---
Write-Host "デフォルトの Podman コネクションを 'claudeVM' に設定しています..."
try {
    podman system connection default claudeVM
    Write-Host "デフォルトコネクションを設定しました。"
} catch {
    # このコマンドはすでに設定されている場合や、machine が起動していない場合に失敗する可能性があります
    # 致命的ではない場合もあるので警告として扱う
    Write-Warning "デフォルトの Podman コネクション設定に失敗しました (既に設定済みか machine の問題かもしれません): $($_.Exception.Message)"
    # ここではスクリプトを終了しない
}

# --- Step 3: DevContainer の起動 ---
Write-Host "現在のフォルダで DevContainer を起動しています..."
try {
    # devcontainer up はコンテナをビルド/起動し、必要なツールをインストールします
    # 実行中は標準出力に進捗が表示されます
    devcontainer up --workspace-folder . --docker-path podman
    Write-Host "DevContainer の起動処理が完了しました。"
} catch {
    Write-Error "DevContainer の起動に失敗しました: $($_.Exception.Message)"
    exit 1 # エラーが発生したらスクリプトを終了
}

# --- Step 4: DevContainer のコンテナIDを取得 ---
Write-Host "DevContainer のコンテナIDを検索しています..."
$currentFolder = (Get-Location).Path
# devcontainer up が設定するラベルを使ってコンテナを特定
# `podman ps` の出力から ID だけを抽出
# .Trim() で取得した文字列の不要な空白を削除
$containerId = $(podman ps --filter "label=devcontainer.local_folder=$currentFolder" --format "{{.ID}}").Trim()

if (-not $containerId) {
    Write-Error "現在のフォルダ ('$currentFolder') に対応する DevContainer のコンテナIDが見つかりませんでした。"
    Write-Error "'devcontainer up' が正常に完了し、コンテナが起動しているか確認してください。"
    exit 1 # コンテナが見つからない場合はスクリプトを終了
}
Write-Host "コンテナIDが見つかりました: $containerId"

# --- Step 5 & 6: コンテナ内でコマンドを実行し、インタラクティブシェルに入る ---
Write-Host "コンテナ ($containerId) 内で 'claude' コマンドを実行し、その後 zsh セッションを開始します..."
try {
    # podman exec -it はインタラクティブなセッションを開始します
    # zsh -c 'claude; exec zsh' の意味:
    #   zsh を非対話モードで起動し、以下のコマンドを実行
    #   'claude;' -> claude コマンドを実行
    #   'exec zsh' -> 現在のプロセス (非対話 zsh) を対話式 zsh に置き換える
    # これにより、claude コマンドが実行された後、自動的にインタラクティブな zsh プロンプトが表示されます。
    podman exec -it $containerId zsh -c 'claude; exec zsh'

    # このコマンドが実行されると、現在のPowerShellセッションはコンテナ内の zsh が終了するまで待機します。
    Write-Host "インタラクティブセッションが終了しました。"

} catch {
    Write-Error "コンテナ内でのコマンド実行に失敗しました: $($_.Exception.Message)"
    exit 1 # エラーが発生したらスクリプトを終了
}

# スクリプトの終了を通知
Write-Host "--- スクリプト完了 ---"

文字コードは、UTF-8(BOM付き)で保存頂けたらと。

Scriptの実行方法

このスクリプトを正しく実行するためには、プロジェクトのフォルダ構成と、実行時のカレントディレクトリが重要になります。
まずは、想定しているフォルダ構成を確認しましょう。

Project/
├── .devcontainer/
│   ├── devcontainer.json
│   ├── Dockerfile
│   └── init-firewall.sh
└── Script/
    └── Claude-Code.ps1  <-- ここにScriptを格納する

上記の構成では、Project というフォルダがプロジェクトのルートディレクトリであり、.devcontainer サブフォルダには DevContainer の設定ファイルなどが、そして Script サブフォルダに今回作成した Claude-Code.ps1 スクリプトが格納されています。

このスクリプトは、内部で devcontainer up --workspace-folder . のように、カレントディレクトリを基準にして DevContainer を起動するコマンドを含んでいます。また、コンテナを特定するためにカレントディレクトリのパスをラベルとして検索しています。

そのため、スクリプトを実行する際は、Project フォルダ自体をカレントディレクトリにした状態で行う必要があります。

それでは、このスクリプトを実行するための具体的な手順をご説明します。

実行手順

  1. カレントディレクトリを Project フォルダに移動する
cd C:\Users\YourUser\Documents\Project
  1. スクリプトを実行する: Project フォルダがカレントディレクトリになっていることを確認したら、以下のコマンドを入力してスクリプトを実行します。
.\Script\Claude-Code.ps1


Scriptを活用してVS Code上でClaude Codeをコンテナ起動している様子

これで、スクリプトが実行され、Podman マシンの起動、DevContainer の起動、そして最終的にコンテナ内での claude コマンドの実行と zsh シェルの開始が自動的に行われます。

無事にスクリプトが完了すると、DevContainer 内の zsh プロンプトが表示され、そのまま作業を続けることができます。

おわりに

いかがでしたか。Vibe Codingが直近流行しつつありますが、PC上のファイルやインストールされているライブラリに影響がでないように取り組んでいきたいですよね。ぜひこの記事が皆さんの参考になれると私としては幸いです。

Accenture Japan (有志)

Discussion