0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

devcontainerで安全にclaude codeを使う

Last updated at Posted at 2025-07-22

まとめ

claude codeを安全に使うと行ったものの、単純にdevcontainerを用意してその中でclaude codeを使うだけの話になります。

ひと手間ありますが、claudeがプロジェクト以外のファイルにアクセスできないようにすることで、より安全に活用することができます。

Anthropicの公式ページDevelopment containers でも紹介されているように claude --dangerously-skip-permissionsをより安全に使う環境として薦められています。

導入手順

1. Dev Containers Extensionを追加

Screenshot 2025-07-22 at 15.08.45.png

2. 設定ファイルの作成: プロジェクトルートに.devcontainer/devcontainer.jsonを作成

言語や開発する内容によって異なるので、今回はPythonのケースで紹介します。

.devcontainer/devcontainer.json
{
    "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の設定項目はたくさんあるので、適宜自分のプロジェクトに合わせて設定していく必要があります。

初めて導入する場合は以下のようなイメージでシンプルなものから始めるのがおすすめです。

  1. まずは提供されているimageを直接使ってみる (e.g. mcr.microsoft.com/devcontainers/python:1-3.12-bullseye)
  2. 必要なfeaturesを探して追加していく (gh, claude, uv, などのcliツールたち)
  3. 提供されているimageでは足りなくなったら Dockerfileを作成してbuildするようにする
  4. 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 で開きます。

Screenshot 2025-07-22 at 18.04.08.png

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が使えるようになります!

Screenshot 2025-07-09 at 22.16.19.png

~/はもちろんコンテナ内なので問題ありません。

そのままだとcliコマンドがない

最初はDockerfileを使わずに直接 "image": "mcr.microsoft.com/devcontainers/python:3.13"を使おうとしていました。しかし必要なcommandが入っていないケースがあります。

gh: command not found

Devcontainer Featuresを使う

"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つありそうです。

  1. GH_TOKENをdevcontainerにセットしてコンテナを起動する
  2. gh auth loginでcredentialsを--unsecure-storageに保存してマウントする

後者はせっかくgh authがkeychainに保存してSecureにCredential情報を管理しているのに反するためWorkaroundとしては、前者を使おうと思います。

こちらの記事で紹介されているやりかたでやります。

.devcontainer/init.sh
#!/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

現状毎回ブラウザで認証するしかなさそうです。

Screenshot 2025-07-10 at 16.03.46.png

Dockerをdevcontainerの中から使う

DBをDockerで立ち上げたりしているケースだとdevcontainerの中からDockerコンテナへアクセスが必要になるので、いくつかの方法があります。

  1. Docker-in-Docker: Docker デーモンをdevcontainer内で立ち上げて使う
  2. Docker-outside-of-Docker: ホストのDockerデーモンを共有する (Example: docker-outside-of-docker-compose
  3. docker-composeを使う (https://code.visualstudio.com/docs/devcontainers/create-dev-container#_use-docker-compose)
    1. Example: Python3 + PostgreSQL

docker compose を使うのがなんだかんだ一番楽かなと重い下の例でもdocker composeを使っています。

pre-commitを自動でinstallしたい

.devcontainer/post-start.sh を用意してその中に pre-commit install など書いて置くことができます。

.devcontainer/devcontainer.json
{
    ...
    "postStartCommand": ".devcontainer/post-start.sh",
}

Devcontainerから抜けたい

Reopen Folder Locally でDevcontainerから抜けられます。

Screenshot 2025-07-22 at 18.03.52.png

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が必要

.devcontainer/docker-compose.yml
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:
.devcontainer/devcontainer.json
{
	"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 とする

Screenshot 2025-07-22 at 17.19.56.png

8000:5000をportsに設定しているので、hostのlocalhost:8000でdevcontainerの5000 portにアクセスできる。

curl localhost:8000/health
{"status":"healthy"}

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?