Connect Claude Code and VSCode using docker containers
- Aug 24
- 7 min read
If you like the idea of using Claude Code but feel cautious about giving it direct access to your machine's file system, a dev container might be exactly what you're looking for. A dev container gives Claude Code an isolated, disposable, and reproducible environment to work in, scoped to a single project instead of your whole machine.
How this works?
A container is a lightweight, isolated environment that packages an application with everything it needs to run (its own file system, tools, and dependencies) separate from your actual machine (the "host"). Docker is the tool that builds and runs containers.
A dev container is a specific convention, defined by the Dev Container spec, for using a container as your full development environment: not just to ship an app, but to write and run code inside it via your editor.
How VS Code fits in: VS Code itself keeps running on your host. The Dev Containers extension connects it to the running container, and everything you do inside that connected window (terminal, language servers, build tools, the Claude Code extension) actually executes inside the container.
What Claude Code can see:
/workspace — your project folder, bind-mounted in from your host so edits show up in your local repository as you work.
/home/vscode/.claude (or /home/devuser/.claude in Option B) — its configuration and session data, stored in the named volume from Step 3.
That's the full extent of it. Your other projects, personal documents, and anything else on your machine are outside the container and simply have no path Claude Code can reach.
When Claude Code runs inside a dev container instead of directly on your machine:
It is isolated, which means that commands executed by Claude run inside the container, not on your host. Anything outside what you have explicitly mounted is invisible to it
The environment in which it runs is defined in a couple of small config files that live in your repository. This is also helpful if you are working with a team and want to share the same setup with Claude Code already installed
It is safer in the sense that any mistake is contained it is more reasonable to let Claude Code to run with a fewer manual approvals than you would allow on your bare machine

What You'll Learn
How to install Claude Code into a dev container
How to persist your Claude Code login across container rebuilds
What Claude Code can and can't see once it is running inside the container
Table of Contents
Prerequisites
Before you begin, make sure you have the following in place:
Docker Desktop: download from docker.com, install, make sure it's running
VS Code: install the Dev Containers extension (ms-vscode-remote.remote-containers)
Claude account (Pro, Max, Team, or Enterprice) you'll authenticate through a browser the first time you run Claude Code.
A GitHub account, if you want to version-control the project (recommended, and used in Step 1 below).
Setup Steps
1. Create a repository on GitHub
Give the project a home before you start configuring anything:
Go to github.com/new and create a new repository (for example, my-first-project).
Initialize it with a README.md.
Clone it to your machine
Add .devcontiner to your folder structure
Inside the cloned repository, add a .devcontainer folder, VS Code specifically looks for this folder in your project root, the name has to match exactly, or VS Code won't detect the configuration and offer to open it as a container.
my-first-project\
├── .devcontainer\
│ └── devcontainer.json
└── (your project files will go here)Create the container configuration file
Inside the .devcontainer folder create a the devcontainer.json file
{
"name": "my-first-project",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"features": {
"ghcr.io/devcontainers/features/node:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1": {}
},
"mounts": [
"source=claude-code-config-${devcontainerId},target=/home/vscode/.claude,type=volume"
],
"postCreateCommand": "sudo chown -R vscode:vscode /home/vscode/.claude",
"customizations": {
"vscode": {
"extensions": [
"github.vscode-pull-request-github"
]
}
},
"remoteUser": "vscode"
}Here's what each part does:
image — the base image to build from. mcr.microsoft.com/devcontainers/base:ubuntu is Microsoft's standard Ubuntu image for dev containers, and it comes with a non-root vscode user already set up. If your project needs a specific language runtime, swap this for one of Microsoft's language-specific base images or add another Feature for it.
features — installs Claude Code. Node.js must be listed explicitly — the Claude Code Feature needs Node/npm to install itself and doesn't reliably install them on its own; leaving it out is a common source of build failures (see Troubleshooting). The :1 version tag pins the Feature's install script, not the Claude Code release — the Feature always installs the latest Claude Code, which then auto-updates itself inside the container by default. Opening the container in VS Code also auto-installs the Claude Code VS Code extension, so you don't list it separately.
mounts — a named volume holding your Claude Code login, explained below.
postCreateCommand — fixes a common permissions mismatch: Docker creates new named volumes owned by root, but the container runs as vscode. Without this line, Claude Code can silently fail to save your login (see Troubleshooting).
customizations.vscode.extensions — additional extensions to auto-install, e.g. github.vscode-pull-request-github for reviewing PRs without leaving the editor.
remoteUser — connects as the non-root vscode user rather than root, which is safer generally and is what later makes it reasonable to run Claude Code with fewer permission prompts.
By default, everything inside a container's home directory — including Claude Code's login token — is discarded when the container rebuilds. The mounts entry above solves this with a named Docker volume, which Docker manages and stores outside any single container, so it survives rebuilds. This is different from a bind mount, which links a folder that already exists on your host into the container. The ${devcontainerId} variable makes the volume unique per project, so each dev container gets its own isolated Claude Code login instead of sharing one across every project on your machine.
Open the project in a Dev Container
Make sure Docker Desktop is running.
In VS Code, go to File → Open Folder and select your project folder.
VS Code detects the .devcontainer configuration and prompts you to Reopen in Container click it. If the prompt doesn't appear, open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and run Dev Containers: Reopen in Container.

The first build takes a couple of minutes.
If you change devcontainer.json or the Dockerfile later, run Dev Containers: Rebuild Container (or Rebuild Without Cache if you're troubleshooting a build failure) from the Command Palette to apply the changes.
Sign in and Start using Claude Code
Open a terminal in VS Code (this terminal runs inside the container, not on your host)
Run:
claudeFollow the authentication prompt. Sign in through a browser window, then you paste a confirmation code back into the terminal.
Thanks to the named volume, this sign-in persists, and you won't need to repeat it the next time you rebuild the container.
From here, you can work with Claude Code exactly as you would on a local install everything it reads, writes, and executes is scoped to /workspace inside the container.
Next Steps
Add a CLAUDE.md file to your project root describing conventions you want Claude Code to follow — it's picked up automatically.
Commit the .devcontainer folder to your repository so teammates get the same environment the moment they open the project.
Browse the official Claude Code documentation for MCP server integrations, custom slash commands, and finer-grained permission settings.
If you're rolling this out for a team rather than just yourself, read Set up Claude Code for your organization and Choose a sandbox environment to compare dev containers against the other isolation options Claude Code supports.
Apendix: Manual Dockerfile alternative
The Feature in Step 3 is the recommended path. If you'd rather see and control every install step explicitly — or you hit a Feature-related build issue you can't resolve — you can install Claude Code with a plain Dockerfile instead.
my-first-project\
├── .devcontainer\
│ ├── devcontainer.json
│ └── Dockerfile
└── ...Dockerfile
FROM python:3.11-slim
RUN apt-get update && apt-get install -y curl git nodejs npm && rm -rf /var/lib/apt/lists/*
RUN npm install -g @anthropic-ai/claude-code
RUN useradd -m -s /bin/bash devuser
USER devuser
WORKDIR /workspaceLets quickly review what this script does:
FROM python:3.11-slim — start from a minimal Linux image that already has Python 3.11 installed. No need to install Python yourself.
RUN apt-get update && apt-get install -y curl git nodejs npm — install system tools. curl for downloads, git for version control, nodejs+npm because Claude Code is a Node.js app. The && rm -rf /var/lib/apt/lists/* at the end just cleans up the installer cache to keep the image small.
RUN npm install -g @anthropic-ai/claude-code — install Claude Code globally using npm (like installing any Node.js CLI tool).
RUN useradd -m -s /bin/bash devuser — create a regular user called devuser. By default Docker runs everything as root (admin), which is risky — this gives you a safer non-root user.
USER devuser — switch to that user for everything that follows.
WORKDIR /workspace — set the default working directory. When you open a terminal in the container, you'll land here. This is also where your project files get mounted.
devcontainer.json
{
"name": "my-first-project",
"build": { "dockerfile": "Dockerfile" },
"mounts": [
"source=${localEnv:USERPROFILE}\\.claude-personal,target=/home/devuser/.claude,type=bind,consistency=cached", "source=${localEnv:USERPROFILE}\\.dbt,target=/home/devuser/.dbt,type=bind,consistency=cached"
],
"customizations": {
"vscode": {
"extensions": [
"anthropic.claude-code",
"github.vscode-pull-request-github"
]
}
},
"remoteUser": "devuser"
}This tells VS Code how to build and configure the container:
name — just a label so VS Code knows what to call this dev container.
build: dockerfile — tells VS Code to build the container using the Dockerfile you created in the same folder.
mounts — connects a folder on your Windows machine to a folder inside the container. Specifically, it maps C:\Users\you\.claude-personal (Windows) to /home/devuser/.claude (container). This is how your Claude Code login session is saved — so you don't have to log in every time you restart the container.
customizations → extensions — VS Code extensions to auto-install inside the container:
anthropic.claude-code — Claude Code
github.vscode-pull-request-github — manage GitHub PRs from inside VS Code
remoteUser — tells VS Code to connect as devuser (the non-root user you created in the Dockerfile), not as root.
Next follow the same process open the folder and vscode will build the container


