mirror of
https://github.com/trailofbits/claude-code-devcontainer
synced 2026-06-21 14:11:48 +00:00
5a2b92a790
* feat: add non-interactive auth via CLAUDE_CODE_OAUTH_TOKEN Bypass the interactive onboarding wizard when CLAUDE_CODE_OAUTH_TOKEN is set. On container create, post_install.py runs `claude -p` to populate auth state and sets hasCompletedOnboarding so the TUI starts without the login wizard. Workaround for https://github.com/anthropics/claude-code/issues/8938. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: use remoteEnv instead of containerEnv for secrets containerEnv bakes values into the image as ENV instructions, visible in docker inspect/history. remoteEnv is set at runtime only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: improve error handling in onboarding bypass - Handle timeout as expected (claude -p writes config before API call) - Catch FileNotFoundError/OSError if claude is not installed - Check returncode explicitly instead of dead CalledProcessError catch - Guard on ~/.claude.json existence before writing onboarding flag - Replace contextlib.suppress with explicit try/except that logs - Update module docstring and README wording Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
75 lines
2.6 KiB
JSON
75 lines
2.6 KiB
JSON
{
|
|
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json",
|
|
"name": "Claude Code Sandbox",
|
|
"build": {
|
|
"dockerfile": "Dockerfile",
|
|
"args": {
|
|
"TZ": "${localEnv:TZ:UTC}",
|
|
"GIT_DELTA_VERSION": "0.18.2",
|
|
"ZSH_IN_DOCKER_VERSION": "1.2.1"
|
|
}
|
|
},
|
|
"features": {
|
|
"ghcr.io/devcontainers/features/github-cli:1": {}
|
|
},
|
|
"runArgs": [
|
|
"--cap-add=NET_ADMIN",
|
|
"--cap-add=NET_RAW"
|
|
],
|
|
"init": true,
|
|
"updateRemoteUserUID": true,
|
|
"customizations": {
|
|
"vscode": {
|
|
"extensions": [
|
|
"anthropic.claude-code"
|
|
],
|
|
"settings": {
|
|
"terminal.integrated.defaultProfile.linux": "zsh",
|
|
"terminal.integrated.profiles.linux": {
|
|
"bash": {
|
|
"path": "bash",
|
|
"icon": "terminal-bash"
|
|
},
|
|
"zsh": {
|
|
"path": "zsh"
|
|
}
|
|
},
|
|
"files.trimTrailingWhitespace": true,
|
|
"files.insertFinalNewline": true,
|
|
"files.trimFinalNewlines": true
|
|
}
|
|
}
|
|
},
|
|
"remoteUser": "vscode",
|
|
"mounts": [
|
|
"source=devc-${localWorkspaceFolderBasename}-bashhistory-${devcontainerId},target=/commandhistory,type=volume",
|
|
"source=devc-${localWorkspaceFolderBasename}-config-${devcontainerId},target=/home/vscode/.claude,type=volume",
|
|
"source=devc-${localWorkspaceFolderBasename}-gh-${devcontainerId},target=/home/vscode/.config/gh,type=volume",
|
|
"source=${localEnv:HOME}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,readonly",
|
|
"source=${localWorkspaceFolder}/.devcontainer,target=/workspace/.devcontainer,type=bind,readonly"
|
|
],
|
|
"containerEnv": {
|
|
"NODE_OPTIONS": "--max-old-space-size=4096",
|
|
"CLAUDE_CONFIG_DIR": "/home/vscode/.claude",
|
|
"POWERLEVEL9K_DISABLE_GITSTATUS": "true",
|
|
"GIT_CONFIG_GLOBAL": "/home/vscode/.gitconfig.local",
|
|
"UV_LINK_MODE": "copy",
|
|
"NPM_CONFIG_IGNORE_SCRIPTS": "true",
|
|
"NPM_CONFIG_AUDIT": "true",
|
|
"NPM_CONFIG_FUND": "false",
|
|
"NPM_CONFIG_SAVE_EXACT": "true",
|
|
"NPM_CONFIG_UPDATE_NOTIFIER": "false",
|
|
"NPM_CONFIG_MINIMUM_RELEASE_AGE": "1440",
|
|
"PYTHONDONTWRITEBYTECODE": "1",
|
|
"PIP_DISABLE_PIP_VERSION_CHECK": "1"
|
|
},
|
|
"remoteEnv": {
|
|
"CLAUDE_CODE_OAUTH_TOKEN": "${localEnv:CLAUDE_CODE_OAUTH_TOKEN:}",
|
|
"ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY:}"
|
|
},
|
|
"initializeCommand": "test -f \"$HOME/.gitconfig\" || touch \"$HOME/.gitconfig\"",
|
|
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated",
|
|
"workspaceFolder": "/workspace",
|
|
"postCreateCommand": "uv run --no-project /opt/post_install.py"
|
|
}
|