まとめ
claude codeを安全に使うと行ったものの、単純にdevcontainerを用意してその中でclaude codeを使うだけの話になります。
ひと手間ありますが、claudeがプロジェクト以外のファイルにアクセスできないようにすることで、より安全に活用することができます。
Anthropicの公式ページDevelopment containers でも紹介されているように claude --dangerously-skip-permissions
をより安全に使う環境として薦められています。
導入手順
1. Dev Containers Extensionを追加
2. 設定ファイルの作成: プロジェクトルートに.devcontainer/devcontainer.jsonを作成
言語や開発する内容によって異なるので、今回はPythonのケースで紹介します。
{
"name": "Python Devcontainer",
// "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye" // 提供されているimageを直接使うことも可能
"build": { // 自分のDockerfileをBuildして開発コンテナに使う
"dockerfile": "Dockerfile",
"context": "."
},
"features": { // gh, claude code, uvなどのツールを追加できる
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "latest"
},
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
"ghcr.io/jsburckhardt/devcontainer-features/uv:1": {}
},
"mounts": [ // 必要に応じてホストマシンのディレクトリをmountする
"source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind",
"source=${localEnv:HOME}/.zsh_history,target=/home/vscode/.zsh_history,type=bind",
"source=${localEnv:HOME}/.zshrc,target=/home/vscode/.zshrc,type=bind"
],
"initializeCommand": ".devcontainer/init.sh",
"runArgs": [
"--env-file",
".devcontainer/.env.devcontainer"
],
"remoteUser": "vscode",
"containerUser": "vscode"
}
このconfig fileの設定項目はたくさんあるので、適宜自分のプロジェクトに合わせて設定していく必要があります。
初めて導入する場合は以下のようなイメージでシンプルなものから始めるのがおすすめです。
- まずは提供されているimageを直接使ってみる (e.g.
mcr.microsoft.com/devcontainers/python:1-3.12-bullseye
) - 必要なfeaturesを探して追加していく (gh, claude, uv, などのcliツールたち)
- 提供されているimageでは足りなくなったら Dockerfileを作成してbuildするようにする
- DBなど他のコンテナにも接続する必要があれば、docker-compose, docker-in-docker, docker-outside-of-dockerなどを考慮していく
Dockerfileは以下のようになります。もちろんこちらもプロジェクトによるので、必要なコマンドなど適宜調整すればよさそうです。このDockerfile自体もClaude Codeに作成してもらいました。
Dockerfile
FROM mcr.microsoft.com/devcontainers/python:3.13
# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive
# Install system packages
RUN apt-get update && apt-get install -y \
git \
curl \
wget \
vim \
nano \
htop \
tree \
jq \
unzip \
zip \
build-essential \
libssl-dev \
libffi-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
libncurses5-dev \
libncursesw5-dev \
xz-utils \
tk-dev \
libxml2-dev \
libxmlsec1-dev \
libffi-dev \
liblzma-dev \
# PostgreSQL client for Task7
postgresql-client \
# For network checks
netcat-traditional \
# For build calculations
bc \
# For Docker in Docker support
docker.io \
# For container management
docker-compose \
# make
make \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install uv (Python package manager)
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/root/.local/bin:$PATH"
# Install pre-commit
RUN pip install pre-commit==4.2.0
# Create workspace directory
WORKDIR /workspace
# Set the default shell to bash
SHELL ["/bin/bash", "-c"]
# Configure git to be safe for the workspace
RUN git config --global --add safe.directory /workspace
# Set up user permissions for vscode user
USER vscode
# Install uv for vscode user
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/home/vscode/.local/bin:$PATH"
# Ensure the workspace is writable by vscode user
RUN sudo chown -R vscode:vscode /workspace
# Set working directory
WORKDIR /workspace
若干不要な設定も入ってるかもしれませんが、適宜調整ということで。
2. VS Codeで開く: VS Codeで「Reopen in Container」を選択
mac の場合は command + p
でパレットを開いて > dev container
とかくと選択肢がでてくるので、Reopen in Container
で開きます。
3. Claude Codeの確認: コンテナ内でClaude Codeが使用可能か確認
コンテナの中でいつもどおりclaude を叩くとcontainerの中でclaudeを使えるようになります。
claude
これによって関係ないホストマシンのファイルを勝手に触られたりすることを防ぐことができます。
初めて使おうとしたときに引っかかること
devcontainerで立ち上げると ~/.claudeの設定読み込めない?
~/.claude
以下に様々なユーザ設定があるのが読み込めないと困ります。Docker volumeを使う方法が紹介されていますが、雑に~/.claudeをマウントしてもいいかなと思いました。session情報や設定がホストマシンと共有できます。
"mounts": [
"source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind"
],
rootユーザだと--dangerously-skip-permissions
が使えない
--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons
せっかくdevcontainerにしたのにYOLOできないと困りますね。
userを指定しましょう。(ref: https://code.visualstudio.com/remote/advancedcontainers/add-nonroot-user)
"removeUser": "vscode"
コンテナ内でwhoami
を打つとvscodeになっています。
whoami
vscode
claude --dangerously-skip-permissions
が使えるようになります!
~/
はもちろんコンテナ内なので問題ありません。
そのままだとcliコマンドがない
最初はDockerfileを使わずに直接 "image": "mcr.microsoft.com/devcontainers/python:3.13"
を使おうとしていました。しかし必要なcommandが入っていないケースがあります。
gh: command not found
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "latest"
}
}
結局他にも必要なコマンドをContainerに入れておく必要があるので、 Dockerfileを作ることにしました。
Claude Codeに作成してもらいました。(今回はPythonとして)
参考までDockerfile
FROM mcr.microsoft.com/devcontainers/python:3.13
# Set environment variables
ENV DEBIAN_FRONTEND=noninteractive
# Install system packages
RUN apt-get update && apt-get install -y \
git \
curl \
wget \
vim \
nano \
htop \
tree \
jq \
unzip \
zip \
build-essential \
libssl-dev \
libffi-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
libncurses5-dev \
libncursesw5-dev \
xz-utils \
tk-dev \
libxml2-dev \
libxmlsec1-dev \
libffi-dev \
liblzma-dev \
# PostgreSQL client for Task7
postgresql-client \
# For network checks
netcat-traditional \
# For build calculations
bc \
# For Docker in Docker support
docker.io \
# For container management
docker-compose \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install uv (Python package manager)
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/root/.local/bin:$PATH"
# Install GitHub CLI
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
&& chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& apt-get update \
&& apt-get install -y gh \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install pre-commit
RUN pip install pre-commit==4.2.0
# Install make (if not already present)
RUN apt-get update && apt-get install -y make && apt-get clean && rm -rf /var/lib/apt/lists/*
# Create workspace directory
WORKDIR /workspace
# Set the default shell to bash
SHELL ["/bin/bash", "-c"]
# Configure git to be safe for the workspace
RUN git config --global --add safe.directory /workspace
# Set up user permissions for vscode user
USER vscode
# Install uv for vscode user
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/home/vscode/.local/bin:$PATH"
# Ensure the workspace is writable by vscode user
RUN sudo chown -R vscode:vscode /workspace
# Set working directory
WORKDIR /workspace
gitの認証をLocalから共有して使う
Sharing Git credentials with your container を使うとホストの認証をコンテナ内で使うことができます。
これがうまく動いていると devcontainer内の ~/.gitconfig
の [credentials]
が以下のようにgit credential helperが指定されている事がわかります。
[credential]
helper = "!f() { /home/vscode/.vscode-server/bin/xxxxx/node /tmp/vscode-remote-containers-xxxxx.js git-credential-helper $*; }; f"
この時点でgit push
git pull
など問題なく行うことができます。
gh認証 (optional)
コンテナに入ってgitは使えるのですが、gh認証は毎回コンテナでgh auth login
をする必要があります。
claude codeではgh commandを使って結構作業してもらうことが多いので、自動的に設定したい気持ちになります。
Optionalですが、コンテナ作成時にホストマシンのgh auth token
を設定するやり方にして一手間省くことができました。
普段ローカルでは、あまり意識してませんが、ほとんどのケースで gh auth login
で gh CLIの認証をしたあとに、 gh の credential helperを使ってgitを使っているのではないでしょうか。
gh auth setup-git
を実行することで gh credential helperをgitのcredential helperにすることができます (gh auth setup-git)
もうすこしgh authの話をすると、MacOSでは、gh auth login
で、keychainにcredentialsが保存されるため、devcontainersのコンテナ内でLocalのgh auth login
で認証したcredentialsを使うのは難しいです。
Once you've authenticated successfully, your credentials are stored in the macOS keychain and will be used every time you clone an HTTPS URL.
何もしないと、以下のようなauthを要求するメッセージが出てしまいます。
HTTP 401: This endpoint requires you to be authenticated. (https://api.github.com/graphql)
Try authenticating with: gh auth login
解決策としては2つありそうです。
- GH_TOKENをdevcontainerにセットしてコンテナを起動する
- gh auth loginでcredentialsを--unsecure-storageに保存してマウントする
後者はせっかくgh authがkeychainに保存してSecureにCredential情報を管理しているのに反するためWorkaroundとしては、前者を使おうと思います。
こちらの記事で紹介されているやりかたでやります。
#!/bin/bash
# check gh token
if which gh &>/dev/null; then
gh auth token | xargs -I {} echo "GH_TOKEN="{} > .devcontainer/.env.devcontainer
fi
{
...
"initializeCommand": ".devcontainer/init.sh",
"runArgs": [
"--env-file",
".devcontainer/.env.devcontainer"
],
...
}
.gitignore
に .env.devcontainer
を追加しておきましょう。
これで、devcontainerに入った段階で GH_TOKEN
で認証されている状態になります。
gh auth status
github.com
✓ Logged in to github.com account nakamasato (GH_TOKEN)
- Active account: true
- Git operations protocol: https
- Token: gho_************************************
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
claude認証 (現状毎回login必要そう)
最近 Long-lived authentication tokenがサポートされたので、環境変数にいれたらいけるかなと思って試しましたがだめでした。
claude
現状毎回ブラウザで認証するしかなさそうです。
Dockerをdevcontainerの中から使う
DBをDockerで立ち上げたりしているケースだとdevcontainerの中からDockerコンテナへアクセスが必要になるので、いくつかの方法があります。
- Docker-in-Docker: Docker デーモンをdevcontainer内で立ち上げて使う
- Docker-outside-of-Docker: ホストのDockerデーモンを共有する (Example: docker-outside-of-docker-compose
- docker-composeを使う (https://code.visualstudio.com/docs/devcontainers/create-dev-container#_use-docker-compose)
- Example: Python3 + PostgreSQL
docker compose を使うのがなんだかんだ一番楽かなと重い下の例でもdocker composeを使っています。
pre-commitを自動でinstallしたい
.devcontainer/post-start.sh
を用意してその中に pre-commit install
など書いて置くことができます。
{
...
"postStartCommand": ".devcontainer/post-start.sh",
}
Devcontainerから抜けたい
Reopen Folder Locally
でDevcontainerから抜けられます。
Appendix: https://github.com/nakamasato/flask-sample にdevcontainerを導入するステップ紹介
最低限のPython imageでDevcontainer起動
{
"name": "Python 3",
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
"remoteUser": "vscode",
"containerUser": "vscode"
}
この時点で、source codeへのアクセス、 gitへのアクセスができる
gh, poetry, claude code などCLIを追加する
{
"name": "Python 3",
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
"ghcr.io/devcontainers-extra/features/poetry:2": {}
},
"remoteUser": "vscode",
"containerUser": "vscode"
}
これで、gh command, claude code, poetry, が使えるようになる
Docker ComposeにしてDBも使えるようにする
このレポではflask appがmysqlへ接続する構成なので、devcontainerでもmysql containerが必要
version: '3.8'
services:
devcontainer:
image: "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye"
volumes:
- ../..:/workspaces:cached
env_file:
- ../docker/env_file/env.app
- ../docker/env_file/env.mysql
command: sleep infinity
ports:
- 5000:5000
mysql:
image: mysql:8.0
restart: unless-stopped
volumes:
- db_data:/var/lib/mysql
- ../docker/mysql/schema/user.sql:/docker-entrypoint-initdb.d/01_schema_user.sql
- ../docker/mysql/data/user.sql:/docker-entrypoint-initdb.d/11_data_user.sql
- ../docker/mysql/conf.d/:/etc/mysql/conf.d/
env_file:
- ../docker/env_file/env.mysql
ports:
- 3306:3306
healthcheck:
test: ["CMD", "mysqladmin", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
db_data:
{
"name": "Python 3",
"dockerComposeFile": "docker-compose.yml",
"service": "devcontainer",
"workspaceFolder": "/workspaces/flask-sample",
"features": {
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
"ghcr.io/devcontainers-extra/features/poetry:2": {}
},
"remoteUser": "vscode",
"containerUser": "vscode"
}
これでflaskが立ち上がるようになる MYSQL_HOST=db FLASK_APP=sample FLASK_ENV=development poetry run flask run --host=0.0.0.0
docker-composeでの mysqlのservice名がdbなので MYSQ_HOST=db
とする
8000:5000
をportsに設定しているので、hostのlocalhost:8000でdevcontainerの5000 portにアクセスできる。
curl localhost:8000/health
{"status":"healthy"}
参考
- VSCode Devcontainer: https://code.visualstudio.com/docs/devcontainers/containers
- claude code: https://docs.anthropic.com/en/docs/claude-code/devcontainer
- devcontainer feature anthropic: https://github.com/anthropics/devcontainer-features
- devcontainer cli: https://github.com/devcontainers/cli
- gh
- Claude CodeをApple Containerの中で動かす
- https://github.com/sooperset/mcp-atlassian/blob/main/.devcontainer/devcontainer.json