二、核心特性
1. 生产就绪的 Node.js 环境:基于 Node.js 20,包含必要的开发依赖
2. 安全设计:自定义防火墙,限制网络访问到必要的服务
3. 开发者友好工具:包含 git、ZSH 和生产力增强工具、fzf 等
4. VS Code 无缝集成:预配置扩展和优化设置
5. 会话持久化:命令历史和配置在容器重启后保留
6. 跨平台支持:兼容 macOS、Windows 和 Linux 开发环境
三、四步快速开始
1. 安装 VS Code 和 Remote – Containers 扩展
2. 参考下方配置详解在工作区创建 .devcontainer 目录及相关文件
3. 在 VS Code 中打开仓库
4. 当提示时,单击 "Reopen in Container"(或使用命令面板:Cmd+Shift+P → "Remote-Containers: Reopen in Container")
四、配置详解
目录结构
your-project/├── .devcontainer/│ ├── devcontainer.json│ ├── Dockerfile│ └── init-firewall.sh└── …
六、方案 1:使用 Dev Containers Feature(推荐)
Dev Containers Feature 是在 Dev Container 中安装 CodeBuddy Code 的推荐方式。它提供自动版本管理、与其他特性配置一致、简化维护等优势。
优势:
·自动版本管理 – 轻松升级到最新版本或固定特定版本
·配置一致性 – 与其他 Dev Containers 特性采用相同配置方式
·简化维护 – 无需在 Dockerfile 中管理复杂的安装逻辑
·团队共享 – 易于在团队中统一配置
配置方法:
在 devcontainer.json 中的 features 字段添加配置:
{ "name": "CodeBuddy Code Sandbox", "features": { "ghcr.io/devcontainers-contrib/features/codebuddy-code:1": { "version": "latest" } }, // … 其他配置}
固定特定版本:
{ "features": { "ghcr.io/devcontainers-contrib/features/codebuddy-code:1": { "version": "2.16.0" } }}
使用默认最新版本:
{ "features": { "ghcr.io/devcontainers-contrib/features/codebuddy-code:1": {} }}
七、方案 2:在 Dockerfile 中手动安装
如果需要更多控制或特殊场景,可在 Dockerfile 中手动安装。详见下方 Dockerfile 部分。
八、1. devcontainer.json
控制容器设置、管理扩展、配置卷挂载。
包含 Dev Containers Feature 的完整示例:
{ "name": "CodeBuddy Code Sandbox", "build": { "dockerfile": "Dockerfile", "args": { "TZ": "${localEnv:TZ:America/Los_Angeles}", "GIT_DELTA_VERSION": "0.18.2", "ZSH_IN_DOCKER_VERSION": "1.2.0" } }, "features": { "ghcr.io/devcontainers-contrib/features/codebuddy-code:1": { "version": "latest" } }, "runArgs": [ "–cap-add=NET_ADMIN", "–cap-add=NET_RAW" ], "customizations": { "vscode": { "extensions": [ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "eamodio.gitlens" ], "settings": { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "terminal.integrated.defaultProfile.linux": "zsh", "terminal.integrated.profiles.linux": { "bash": { "path": "bash", "icon": "terminal-bash" }, "zsh": { "path": "zsh" } } } } }, "remoteUser": "node", "mounts": [ "source=codebuddy-code-bashhistory-${devcontainerId},target=/commandhistory,type=volume", "source=codebuddy-code-config-${devcontainerId},target=/home/node/.codebuddy,type=volume" ], "containerEnv": { "NODE_OPTIONS": "–max-old-space-size=4096", "CODEBUDDY_CONFIG_DIR": "/home/node/.codebuddy", "POWERLEVEL9K_DISABLE_GITSTATUS": "true" }, "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated", "workspaceFolder": "/workspace", "postStartCommand": "sudo /usr/local/bin/init-firewall.sh", "waitFor": "postStartCommand"}
关键配置说明:
·features – 声明使用 CodeBuddy Code Dev Containers Feature,支持版本管理
·version: "latest" – 使用最新版本(可替换为具体版本号如 "2.16.0")
·注意:使用 Feature 方式时,Dockerfile 中无需 CODEBUDDY_CODE_VERSION 参数
九、2. Dockerfile
定义容器镜像、指定安装的工具。
十、使用 Feature 时的简化 Dockerfile
如使用上方 Dev Containers Feature 安装 CodeBuddy Code,Dockerfile 可以更简洁(无需 CODEBUDDY_CODE_VERSION 参数和手动安装命令):
注意:说明:
注意:如果你选择使用 Dev Containers Feature 方式(推荐),可以参考下方"简化版 Dockerfile"。如需在 Dockerfile 中手动安装,可参考"完整版 Dockerfile"。
简化版 Dockerfile(推荐配合 Feature 使用):
FROM node:20ARG TZENV TZ="$TZ"# Install basic development tools and iptables/ipsetRUN apt-get update && apt-get install -y –no-install-recommends \\ less \\ git \\ procps \\ sudo \\ fzf \\ zsh \\ man-db \\ unzip \\ gnupg2 \\ gh \\ iptables \\ ipset \\ iproute2 \\ dnsutils \\ aggregate \\ jq \\ nano \\ vim \\ && apt-get clean && rm -rf /var/lib/apt/lists/*# Ensure default node user has access to /usr/local/shareRUN mkdir -p /usr/local/share/npm-global && \\ chown -R node:node /usr/local/shareARG USERNAME=node# Persist bash history.RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \\ && mkdir /commandhistory \\ && touch /commandhistory/.bash_history \\ && chown -R $USERNAME /commandhistory# Set `DEVCONTAINER` environment variable to help with orientationENV DEVCONTAINER=true# Create workspace and config directories and set permissionsRUN mkdir -p /workspace /home/node/.codebuddy && \\ chown -R node:node /workspace /home/node/.codebuddyWORKDIR /workspaceARG GIT_DELTA_VERSION=0.18.2RUN ARCH=$(dpkg –print-architecture) && \\ wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \\ sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \\ rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"# Set up non-root userUSER node# Install global packagesENV NPM_CONFIG_PREFIX=/usr/local/share/npm-globalENV PATH=$PATH:/usr/local/share/npm-global/bin# Set the default shell to zsh rather than shENV SHELL=/bin/zsh# Set the default editor and visualENV EDITOR=nanoENV VISUAL=nano# Default powerline10k themeARG ZSH_IN_DOCKER_VERSION=1.2.0RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" — \\ -p git \\ -p fzf \\ -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \\ -a "source /usr/share/doc/fzf/examples/completion.zsh" \\ -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \\ -x# CodeBuddy Code will be installed via Dev Containers Feature# Copy and set up firewall scriptCOPY init-firewall.sh /usr/local/bin/USER rootRUN chmod +x /usr/local/bin/init-firewall.sh && \\ echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \\ chmod 0440 /etc/sudoers.d/node-firewallUSER node
十一、手动安装方式的完整 Dockerfile
如需完全控制安装过程,可在 Dockerfile 中手动安装 CodeBuddy Code(此方案不使用 Dev Containers Feature):
FROM node:20ARG TZENV TZ="$TZ"ARG CODEBUDDY_CODE_VERSION=latest# Install basic development tools and iptables/ipsetRUN apt-get update && apt-get install -y –no-install-recommends \\ less \\ git \\ procps \\ sudo \\ fzf \\ zsh \\ man-db \\ unzip \\ gnupg2 \\ gh \\ iptables \\ ipset \\ iproute2 \\ dnsutils \\ aggregate \\ jq \\ nano \\ vim \\ && apt-get clean && rm -rf /var/lib/apt/lists/*# Ensure default node user has access to /usr/local/shareRUN mkdir -p /usr/local/share/npm-global && \\ chown -R node:node /usr/local/shareARG USERNAME=node# Persist bash history.RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \\ && mkdir /commandhistory \\ && touch /commandhistory/.bash_history \\ && chown -R $USERNAME /commandhistory# Set `DEVCONTAINER` environment variable to help with orientationENV DEVCONTAINER=true# Create workspace and config directories and set permissionsRUN mkdir -p /workspace /home/node/.codebuddy && \\ chown -R node:node /workspace /home/node/.codebuddyWORKDIR /workspaceARG GIT_DELTA_VERSION=0.18.2RUN ARCH=$(dpkg –print-architecture) && \\ wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \\ sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \\ rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"# Set up non-root userUSER node# Install global packagesENV NPM_CONFIG_PREFIX=/usr/local/share/npm-globalENV PATH=$PATH:/usr/local/share/npm-global/bin# Set the default shell to zsh rather than shENV SHELL=/bin/zsh# Set the default editor and visualENV EDITOR=nanoENV VISUAL=nano# Default powerline10k themeARG ZSH_IN_DOCKER_VERSION=1.2.0RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" — \\ -p git \\ -p fzf \\ -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \\ -a "source /usr/share/doc/fzf/examples/completion.zsh" \\ -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \\ -x# Install CodeBuddy Code (manual installation method – only if not using Dev Containers Feature)RUN npm install -g @tencent-ai/codebuddy-code@${CODEBUDDY_CODE_VERSION}# Copy and set up firewall scriptCOPY init-firewall.sh /usr/local/bin/USER rootRUN chmod +x /usr/local/bin/init-firewall.sh && \\ echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \\ chmod 0440 /etc/sudoers.d/node-firewallUSER node
注意:若使用此方式,devcontainer.json 中的 build.args 需包含 "CODEBUDDY_CODE_VERSION" 参数,且 features 字段中不应包含 CodeBuddy Code Feature。
十二、3. init-firewall.sh
建立网络安全规则。
#!/bin/bashset -euo pipefail # Exit on error, undefined vars, and pipeline failuresIFS=$'\\n\\t' # Stricter word splitting# 1. Extract Docker DNS info BEFORE any flushingDOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\\.0\\.0\\.11" || true)# Flush existing rules and delete existing ipsetsiptables -Fiptables -Xiptables -t nat -Fiptables -t nat -Xiptables -t mangle -Fiptables -t mangle -Xipset destroy allowed-domains 2>/dev/null || true# 2. Selectively restore ONLY internal Docker DNS resolutionif [ -n "$DOCKER_DNS_RULES" ]; then echo "Restoring Docker DNS rules…" iptables -t nat -N DOCKER_OUTPUT 2>/dev/null || true iptables -t nat -N DOCKER_POSTROUTING 2>/dev/null || true echo "$DOCKER_DNS_RULES" | xargs -L 1 iptables -t natelse echo "No Docker DNS rules to restore"fi# First allow DNS and localhost before any restrictions# Allow outbound DNSiptables -A OUTPUT -p udp –dport 53 -j ACCEPT# Allow inbound DNS responsesiptables -A INPUT -p udp –sport 53 -j ACCEPT# Allow outbound SSHiptables -A OUTPUT -p tcp –dport 22 -j ACCEPT# Allow inbound SSH responsesiptables -A INPUT -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT# Allow localhostiptables -A INPUT -i lo -j ACCEPTiptables -A OUTPUT -o lo -j ACCEPT# Create ipset with CIDR supportipset create allowed-domains hash:net# Fetch GitHub meta information and aggregate + add their IP rangesecho "Fetching GitHub IP ranges…"gh_ranges=$(curl -s https://api.github.com/meta)if [ -z "$gh_ranges" ]; then echo "ERROR: Failed to fetch GitHub IP ranges" exit 1fiif ! echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null; then echo "ERROR: GitHub API response missing required fields" exit 1fiecho "Processing GitHub IPs…"while read -r cidr; do if [[ ! "$cidr" =~ ^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then echo "ERROR: Invalid CIDR range from GitHub meta: $cidr" exit 1 fi echo "Adding GitHub range $cidr" ipset add allowed-domains "$cidr"done < <(echo "$gh_ranges" | jq -r '(.web + .api + .git)[]' | aggregate -q)# Resolve and add other allowed domainsfor domain in \\ "registry.npmjs.org" \\ "copilot.tencent.com" \\ "sentry.io" \\ "marketplace.visualstudio.com" \\ "vscode.blob.core.windows.net" \\ "update.code.visualstudio.com"; do echo "Resolving $domain…" ips=$(dig +noall +answer A "$domain" | awk '$4 == "A" {print $5}') if [ -z "$ips" ]; then echo "ERROR: Failed to resolve $domain" exit 1 fi while read -r ip; do if [[ ! "$ip" =~ ^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$ ]]; then echo "ERROR: Invalid IP from DNS for $domain: $ip" exit 1 fi echo "Adding $ip for $domain" ipset add allowed-domains "$ip" done < <(echo "$ips")done# Get host IP from default routeHOST_IP=$(ip route | grep default | cut -d" " -f3)if [ -z "$HOST_IP" ]; then echo "ERROR: Failed to detect host IP" exit 1fiHOST_NETWORK=$(echo "$HOST_IP" | sed "s/\\.[0-9]*$/.0\\/24/")echo "Host network detected as: $HOST_NETWORK"# Set up remaining iptables rulesiptables -A INPUT -s "$HOST_NETWORK" -j ACCEPTiptables -A OUTPUT -d "$HOST_NETWORK" -j ACCEPT# Set default policies to DROP firstiptables -P INPUT DROPiptables -P FORWARD DROPiptables -P OUTPUT DROP# First allow established connections for already approved trafficiptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPTiptables -A OUTPUT -m state –state ESTABLISHED,RELATED -j ACCEPT# Then allow only specific outbound traffic to allowed domainsiptables -A OUTPUT -m set –match-set allowed-domains dst -j ACCEPT# Explicitly REJECT all other outbound traffic for immediate feedbackiptables -A OUTPUT -j REJECT –reject-with icmp-admin-prohibitedecho "Firewall configuration complete"echo "Verifying firewall rules…"if curl –connect-timeout 5 https://example.com >/dev/null 2>&1; then echo "ERROR: Firewall verification failed – was able to reach https://example.com" exit 1else echo "Firewall verification passed – unable to reach https://example.com as expected"fi# Verify GitHub API accessif ! curl –connect-timeout 5 https://api.github.com/zen >/dev/null 2>&1; then echo "ERROR: Firewall verification failed – unable to reach https://api.github.com" exit 1else echo "Firewall verification passed – able to reach https://api.github.com as expected"fi
十三、安全特性
容器实现了多层安全防护:
·精确访问控制:限制出站连接到白名单域名(npm registry、GitHub、CodeBuddy API 等)
·允许的出站连接:防火墙允许出站 DNS 和 SSH 连接
·默认拒绝策略:阻止所有其他外部网络访问
·启动验证:容器初始化时验证防火墙规则
·隔离:创建与主系统分离的安全开发环境
十四、重要安全提示
虽然开发容器提供了实质性的保护,但没有系统能够完全免疫所有攻击。当使用 -y (或 –dangerously-skip-permissions) 执行时,开发容器无法阻止恶意项目窃取容器内可访问的任何内容,包括 CodeBuddy Code 凭证。我们建议仅在处理可信仓库时使用开发容器。 始终保持良好的安全实践并监控 CodeBuddy 的活动。
十五、无人值守操作
容器增强的安全措施(隔离和防火墙规则)允许你运行 codebuddy -y (或 codebuddy –dangerously-skip-permissions) 来绕过权限提示,实现无人值守操作。
十六、自定义选项
开发容器配置设计灵活,可根据需求调整:
·根据工作流添加或删除 VS Code 扩展
·为不同硬件环境调整资源分配
·调整网络访问权限
·自定义 shell 配置和开发工具
十八、1. 安全的客户项目开发
使用开发容器隔离不同客户的项目,确保代码和凭证永不混合。
十九、2. 团队快速入职
新团队成员可在几分钟内获得完全配置的开发环境,所有必要的工具和设置都已预装。
20、3. 一致的 CI/CD 环境
在 CI/CD 流水线中镜像你的开发容器配置,确保开发和生产环境匹配。
21、相关资源
·VS Code 开发容器文档
·Bash 沙箱
·设置配置
·GitLab CI/CD 集成
·Official Dev Containers Docs
·devcontainers-contrib/features