Skip to content

Instantly share code, notes, and snippets.

@LeoVS09
Created March 6, 2026 21:35
Show Gist options
  • Select an option

  • Save LeoVS09/20f7feab7e698311dee88718155988d2 to your computer and use it in GitHub Desktop.

Select an option

Save LeoVS09/20f7feab7e698311dee88718155988d2 to your computer and use it in GitHub Desktop.
Dev Container for Claude Code

Development

Claude Code Dev Container

This project uses Dev Containers, which included in VS Code, Cursor, Antigravity. You can use bottom left corner button to open Dev Container view, and then click on "Reopen in Container" button to open the project in a container.

Or you can use cli. In order to activate it, run following in your IDE:

Press cmd/ctrl+shift+p or F1 and select the Dev Containers: Install devcontainer CLI command to install it.

Then you can run the following command to open the project in a container:

devcontainer up && devcontainer exec --workspace-folder . bash

To attach new console to container use this commands:

docker ps
docker exec -it -u node <container_id> zsh
#!/usr/bin/env bash
set -euo pipefail
# .devcontainer/configure-claude.sh
echo "πŸ”§ Configuring Claude Code environment..."
# -- Verify API key is available --
if [ -z "${ANTHROPIC_API_KEY:-}" ]; then
echo "⚠️ ANTHROPIC_API_KEY is not set, claude will prompt login."
else
echo "βœ… ANTHROPIC_API_KEY is configured."
fi
if [ ! -f .claude/settings.json ]; then
echo "πŸ”§ Creating ~/.claude/settings.json..."
mkdir -p ~/.claude
cat > ~/.claude/settings.json << 'EOF'
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo 'git diff:' && git diff --stat && echo 'git status:' && git status"
}
]
}
]
},
"statusLine": {
"type": "command",
"command": "input=$(cat); model=$(echo \"$input\" | jq -r '.model.display_name // .model.id'); style=$(echo \"$input\" | jq -r '.output_style.name // \"default\"'); total_input=$(echo \"$input\" | jq -r '.context_window.total_input_tokens // 0'); total_output=$(echo \"$input\" | jq -r '.context_window.total_output_tokens // 0'); context_size=$(echo \"$input\" | jq -r '.context_window.context_window_size // 0'); total_used=$((total_input + total_output)); if [ \"$context_size\" -gt 0 ]; then percentage=$(awk \"BEGIN {printf \\\"%.1f\\\", ($total_used / $context_size) * 100}\"); else percentage=\"0.0\"; fi; if [ \"$total_used\" -ge 1000 ]; then used_display=$(awk \"BEGIN {printf \\\"%.1fK\\\", $total_used / 1000}\"); else used_display=\"${total_used}\"; fi; if [ \"$context_size\" -ge 1000 ]; then size_display=$(awk \"BEGIN {printf \\\"%.0fK\\\", $context_size / 1000}\"); else size_display=\"${context_size}\"; fi; git_branch=$(git -c core.fileMode=false config advice.detachedHead false 2>/dev/null && git branch --show-current 2>/dev/null || echo \"no-git\"); printf '\\033[01;36m%s\\033[00m \\033[90m|\\033[00m \\033[01;33mOutput style: %s\\033[00m \\033[90m|\\033[00m \\033[01;35m%s/%s (%s%%)\\033[00m \\033[90m|\\033[00m \\033[01;32m%s\\033[00m \\033[90m|\\033[00m \\033[2;37mEsc: interrupt\\033[00m \\033[90m|\\033[00m \\033[2;37madd ultrathink to think longer\\033[00m' \"$model\" \"$style\" \"$used_display\" \"$size_display\" \"$percentage\" \"$git_branch\""
},
"alwaysThinkingEnabled": true,
"skipDangerousModePermissionPrompt": true
}
EOF
echo "βœ… Created .claude/settings.json with default permissions."
fi
retry() {
local max_attempts="${RETRY_ATTEMPTS:-3}"
local delay="${RETRY_DELAY:-1}"
local attempt=1
while [ "$attempt" -le "$max_attempts" ]; do
if "$@"; then
return 0
fi
echo "⚠️ Attempt $attempt/$max_attempts failed: $*"
if [ "$attempt" -lt "$max_attempts" ]; then
echo " Retrying in ${delay}s..."
sleep "$delay"
fi
attempt=$((attempt + 1))
done
echo "❌ All $max_attempts attempts failed: $*"
return 1
}
# echo "πŸ”§ Installing typescript lsp..."
retry claude plugin marketplace add anthropics/claude-plugins-official
retry claude plugin install typescript-lsp@claude-plugins-official
# echo "πŸ”§ Installing context-engineering-kit plugins..."
retry claude plugin marketplace add NeoLabHQ/context-engineering-kit
retry claude plugin install sdd@context-engineering-kit
retry claude plugin install sadd@context-engineering-kit
retry claude plugin install git@context-engineering-kit
echo "πŸš€ Claude Code environment ready."
echo "Use claude /config to disable compaction"
echo "Use claude --dangerously-skip-permissions to run claude"
// .devcontainer/devcontainer.json
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
{
"name": "Node 22 (bookworm) + Claude Code",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/javascript-node:24-bullseye",
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
// "ghcr.io/devcontainers/features/common-utils:2": {
// "installZsh": true,
// "configureZshAsDefaultShell": true,
// "upgradePackages": true,
// "username": "node"
// },
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
"ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
// "ghcr.io/meaningful-ooo/devcontainer-features/homebrew:2": {},
"ghcr.io/devcontainers-extra/features/bash-command:1": {
"command": "npm install -g typescript-language-server typescript"
}
},
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
"settings": {
"terminal.integrated.defaultProfile.linux": "zsh"
},
"extensions": [
"streetsidesoftware.code-spell-checker",
"anthropic.claude-code",
"dbaeumer.vscode-eslint",
"redhat.vscode-yaml",
"redhat.vscode-xml",
"redhat.vscode-json"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [3000, 8080],
// Use 'portsAttributes' to set default properties for specific forwarded ports.
// More info: https://containers.dev/implementors/json_reference/#port-attributes
"portsAttributes": {
"3000": {
"label": "Dev Server",
"onAutoForward": "notify"
}
},
// -- Environment variables --
"containerEnv": {
"NODE_ENV": "development"
},
"remoteEnv": {
// if anthropic api key is set, will skip login
"ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY}"
},
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand":{
// "install-codemap": "sudo brew tap JordanCoin/tap && sudo brew install codemap",
"install-deps": "npm install"
},
// -- Run configuration script on every container start --
"postStartCommand": "if [ -f .devcontainer/configure-claude.sh ]; then bash .devcontainer/configure-claude.sh; fi",
"remoteUser": "node"
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment