Site icon imageTomoMemo.dev

Memo on programming for Junior SWE. Provided by Tomo with passion.

[devcontainer]Claude Codeをコンテナ環境で構築する

きっかけ

  • ローカルの環境とClaude Codeを操作する環境を分けたい
  • Claude Codeの予期せぬ動作でローカルの環境が変わることを避けたい

上記を踏まえて、ここを目指して環境を作ります。

  • どのリポジトリでの開発においてもローカル環境がきれいなままClaude Codeを使える状態にする
  • 理想はコンテナ環境で構築してどのリポジトリにおいても開発ができる状態に..できたら最高

ざっくりとした流れ

  • 前提
    • VSCode、またはVSCodeをForkしたIDEを使う
    • Macbook(M2)を使う(Windowsでの開発はしたことがないので省略します)
    • Docker Desktopをインストール

  • DevContainerの拡張機能を入れる
  • devcontainer cliを入れる
    • npm install -g @devcontainers/cli
  • Claude Codeのリポジトリをgit cloneでローカルに落としてくる
  • claude-code/直下にある.devcontainer/リポジトリをコピー
  • Claude Codeを使いたいディレクトリを作成してコピーした.devcontainer/を入れる
  • VSCode, Cursor, WindSurfなどのIDEでディレクトリを開く
  • Cmd+Shift+Pを押してDevContainers: Reopen in Containerをクリックできる状態を準備する(ここではまだやらない)

上記を踏まえてclaude-code-testというディレクトリに.devcontainerが入っている状態を作る。

claude-code-testの中身

claude-codeリポジトリをgit cloneする。

https://github.com/anthropics/claude-code/tree/main

.devcontainer箇所をいつでもコピーできるように使いやすいフォルダに入れておく。

claude-code-testディレクトリを新規作成、下記の状態を作る。

[claude-code-test]
.
└── .devcontainer
   ├── Dockerfile
   ├── devcontainer.json
   └── init-firewall.sh

devcontainer featuresについて

devcontainer featuresとは、開発用コンテナに機能(ツールや設定)を追加するパッケージのこと。たとえば「Node.jsを入れたい」「Pythonの特定バージョンを使いたい」といった要望を、Featureとして追加することができる。

https://github.com/anthropics/devcontainer-features

このリポジトリはdevcontainer環境でClaude Code Cliにおけるdevcontainer featuresを提供・管理するもの。このリポジトリがあるので、devcontainer.jsonにfeatureを定義するだけでClaude Code cliが自動でセットアップされる。

Claude Codeを実行するだけの場合、このリポジトリを直接実行するわけではないので誤解なきように。自分なりにカスタマイズしたい場合はこのリポジトリをcloneしてfeatureを追加してビルドやテストの実行コマンドを試すこと。

これをしなくても、今回のやり方でClaude Codeはコンテナ環境でつかえるようになる。

なお、これ以降コンテナ環境のことをdevcontainer環境と呼ぶ。

devcontainer環境のsetup手順
  • Docker desktopを開く
  • Cmd+Shift+Pを押してDevContainers: Reopen in Containerをクリック
    • workspace[開発コンテナ: Claude Code Sandbox@desktop-linux]がリモートコンテナで立ち上がる

上記workspaceを初めて立ち上げる場合は時間を要するので気長に待つ。

ここまでで、devcontainer環境を通じてClaude Codeを立ち上げることができる。

  • claudeコマンドを実行
  • claude codeが立ち上がることを確認する
  • 初期設定でOpusが割り当てられているはずなので/model sonnet でsonnetに変更しておくといい
    • 複雑な作業時に/model opusを使うように設定しなおす

/workspaceの概念
  • /workspaceとはdevcontainer内の作業ディレクトリ
  • ローカルマシンのディレクトリとリンクしている
  • .devcontainer.jsonの中身
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated"
"workspaceFolder": "/workspace",
  • 設定の詳細
    • source=${localWorkspaceFolder} = ローカルマシンのプロジェクトフォルダ
    • target=/workspace = コンテナ内の目的地
    • type=bind = 双方向同期(ファイルの変更が両方に反映)

作業ディレクトリを/workspaceと定義している。

つまり下記が成り立つ。

ローカルマシン                     DevContainer
┌─────────────────────┐         ┌─────────────────────┐
│ /Users/you/claude-  │         │                     │
│ code-test/          │   ←→    │ /workspace/         │
│ ├── .devcontainer/  │  Sync   │ ├── .devcontainer/  │
│ ├── src/            │         │ ├── src/            │
│ └── ...             │         │ └── ...             │
└─────────────────────┘         └─────────────────────┘

設定上、双方向に同期ができるため、開発コンテナを落とさない限り、ローカルでも、リモートでも開発をすることができる。

参考:Developing inside a Container

https://code.visualstudio.com/docs/devcontainers/containers

そこで論点となるのが、devcontainer環境下で開発を進めるのか?ローカル環境で開発をするのか?ということ。

devcontainer環境下で開発するのか?ローカル環境で開発するのか?
  • チーム開発や環境差異をなくしたいなら「コンテナ環境」がベスト
  • 個人開発や軽い作業なら「ローカル環境」でもOK

チーム開発前提なら圧倒的にdevcontainer環境下、個人開発や学習においてはローカル環境でもOK。設定上、devcontainer、ローカル双方向に同期ができる。

では最後にローカル環境でも、devcontainer環境のClaude Codeをmountして使う方法をメモとして残す。

ローカル環境でClaude Code(devcontainer)を使う
  • プロジェクトディレクトリで実行
devcontainer up --workspace-folder .
  • devcontainerへ入る
devcontainer exec --workspace-folder . bash
  • コンテナ内の場所を確認
pwd
# /workspaceと返ってくるはず
  • claudeとタイプしてclaude codeが立ち上がることを確認する
  • devcontainerを落とす
    • 以下参照、割愛

ここまでやると、devcontainer環境・ローカル環境どちらでもclaude codeを使うことができるようになる。

コンテナ環境・Docker Imagesを削除する

最後に、不要なコンテナ環境・Docker Imageを削除する手順。

devcontainer環境を終了・削除、docker imageを停止・削除する場合、devcontainer環境、ローカル環境のどちらで行う方がいいのか?

個人的にはローカル環境で行う方が良い(としている)

  • 自分自身を削除できない
    • Dev Container環境内から自分自身を削除しようとすると問題が発生する可能性大(こわくてこちらはやってない)
  • Docker デーモンへのアクセス
    • ローカル環境の方がDockerデーモンに直接アクセスできて確実に削除できる
  • 安全性
    • ローカル環境から操作する方が予期しない問題を避けられるのでは?

削除する手順
  • 削除対象のコンテナ・Docker Imagesを調べる
docker ps -a --filter label=devcontainer.local_folder=/Users/<YOURNAME>/<dev>/<claude-code-test>

今回はdevディレクトリ内にclaude-code-testを作っているのでこのpathになっている。

  • コンテナIDを指定して停止・削除
docker stop <bccb7efe60e1> && docker rm <bccb7efe60e1>

  •  Dev Container用のDockerイメージを削除する
docker rmi <vsc-claude-code-test-735840d248d6c13685eceb8d74b1eed12d9e9d6e343f72eed140dae0caa14175>

[補足]

vsc-claude-code-test-735840d248d6c13685eceb8d74b1eed12d9e9d6e343f72eed140dae0caa14175
│    │                │
│    │                └── ハッシュ値(設定ファイルの内容から生成)
│    └── プロジェクト名
└── VS Code Dev Container接頭辞

  • 一括削除するならこちら

このコードを実行する前に、pwdでcurrent dirのパスをコピーしておくと楽。Warpというターミナルを使うとこちらをコピペすればOK。

# コンテナ停止・削除
docker ps -a --filter label=devcontainer.local_folder=/Users/<YOURNAME>/<dev>/<claude-code-test> -q | xargs docker rm -f

# イメージ削除
docker images | grep claude-code-test | awk '{print $3}' | xargs docker rmi -f

# ボリューム削除
docker volume ls | grep claude-code | awk '{print $2}' | xargs docker volume rm

最後に、.devcontainer/はgit commitすべきか?しないべきか?こちらは、各環境を統一する観点でしておいたほうがいい…というのが私の持論。

参考

https://docs.anthropic.com/en/docs/claude-code/devcontainer

Powered by Tomo with passion.