开发容器

2026-09-18   访问量:0


概述

CodeBuddy Code 开发容器提供了一个预配置、安全的开发环境,适合需要一致性和隔离性工作空间的团队使用。它与 Visual Studio Code 的 Dev Containers 扩展以及类似工具无缝集成。

核心特性

生产就绪的 Node.js 环境:基于 Node.js 20,包含必要的开发依赖

安全设计:自定义防火墙,限制网络访问到必要的服务

开发者友好工具:包含 git、ZSH 和生产力增强工具、fzf 等

VS Code 无缝集成:预配置扩展和优化设置

会话持久化:命令历史和配置在容器重启后保留

跨平台支持:兼容 macOS、Windows 和 Linux 开发环境

四步快速开始

安装 VS Code 和 Remote - Containers 扩展

参考下方配置详解在工作区创建 .devcontainer 目录及相关文件

在 VS Code 中打开仓库

当提示时,单击 "Reopen in Container"(或使用命令面板:Cmd+Shift+P → "Remote-Containers: Reopen in Container")

配置详解

目录结构

your-project/├── .devcontainer/│   ├── devcontainer.json│   ├── Dockerfile│   └── init-firewall.sh└── ...

安装 CodeBuddy Code(推荐方案)

方案 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:20



ARG TZ

ENV TZ="$TZ"



# Install basic development tools and iptables/ipset

RUN 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/share

RUN mkdir -p /usr/local/share/npm-global && \

 chown -R node:node /usr/local/share



ARG 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 orientation

ENV DEVCONTAINER=true



# Create workspace and config directories and set permissions

RUN mkdir -p /workspace /home/node/.codebuddy && \

 chown -R node:node /workspace /home/node/.codebuddy



WORKDIR /workspace



ARG GIT_DELTA_VERSION=0.18.2

RUN 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 user

USER node



# Install global packages

ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global

ENV PATH=$PATH:/usr/local/share/npm-global/bin



# Set the default shell to zsh rather than sh

ENV SHELL=/bin/zsh



# Set the default editor and visual

ENV EDITOR=nano

ENV VISUAL=nano



# Default powerline10k theme

ARG ZSH_IN_DOCKER_VERSION=1.2.0

RUN 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 script

COPY init-firewall.sh /usr/local/bin/

USER root

RUN 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-firewall

USER node

手动安装方式的完整 Dockerfile

如需完全控制安装过程,可在 Dockerfile 中手动安装 CodeBuddy Code(此方案不使用 Dev Containers Feature):

FROM node:20



ARG TZ

ENV TZ="$TZ"



ARG CODEBUDDY_CODE_VERSION=latest



# Install basic development tools and iptables/ipset

RUN 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/share

RUN mkdir -p /usr/local/share/npm-global && \

 chown -R node:node /usr/local/share



ARG 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 orientation

ENV DEVCONTAINER=true



# Create workspace and config directories and set permissions

RUN mkdir -p /workspace /home/node/.codebuddy && \

 chown -R node:node /workspace /home/node/.codebuddy



WORKDIR /workspace



ARG GIT_DELTA_VERSION=0.18.2

RUN 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 user

USER node



# Install global packages

ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global

ENV PATH=$PATH:/usr/local/share/npm-global/bin



# Set the default shell to zsh rather than sh

ENV SHELL=/bin/zsh



# Set the default editor and visual

ENV EDITOR=nano

ENV VISUAL=nano



# Default powerline10k theme

ARG ZSH_IN_DOCKER_VERSION=1.2.0

RUN 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 script

COPY init-firewall.sh /usr/local/bin/

USER root

RUN 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-firewall

USER node

注意:

若使用此方式,devcontainer.json 中的 build.args 需包含 "CODEBUDDY_CODE_VERSION" 参数,且 features 字段中不应包含 CodeBuddy Code Feature。

3. init-firewall.sh

建立网络安全规则。

#!/bin/bash

set -euo pipefail  # Exit on error, undefined vars, and pipeline failures

IFS=$'\n\t'       # Stricter word splitting



# 1. Extract Docker DNS info BEFORE any flushing

DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11" || true)



# Flush existing rules and delete existing ipsets

iptables -F

iptables -X

iptables -t nat -F

iptables -t nat -X

iptables -t mangle -F

iptables -t mangle -X

ipset destroy allowed-domains 2>/dev/null || true



# 2. Selectively restore ONLY internal Docker DNS resolution

if [ -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 nat

else

   echo "No Docker DNS rules to restore"

fi



# First allow DNS and localhost before any restrictions

# Allow outbound DNS

iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

# Allow inbound DNS responses

iptables -A INPUT -p udp --sport 53 -j ACCEPT

# Allow outbound SSH

iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT

# Allow inbound SSH responses

iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

# Allow localhost

iptables -A INPUT -i lo -j ACCEPT

iptables -A OUTPUT -o lo -j ACCEPT



# Create ipset with CIDR support

ipset create allowed-domains hash:net



# Fetch GitHub meta information and aggregate + add their IP ranges

echo "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 1

fi



if ! echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null; then

   echo "ERROR: GitHub API response missing required fields"

   exit 1

fi



echo "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 domains

for 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 route

HOST_IP=$(ip route | grep default | cut -d" " -f3)

if [ -z "$HOST_IP" ]; then

   echo "ERROR: Failed to detect host IP"

   exit 1

fi



HOST_NETWORK=$(echo "$HOST_IP" | sed "s/\.[0-9]*$/.0\/24/")

echo "Host network detected as: $HOST_NETWORK"



# Set up remaining iptables rules

iptables -A INPUT -s "$HOST_NETWORK" -j ACCEPT

iptables -A OUTPUT -d "$HOST_NETWORK" -j ACCEPT



# Set default policies to DROP first

iptables -P INPUT DROP

iptables -P FORWARD DROP

iptables -P OUTPUT DROP



# First allow established connections for already approved traffic

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT



# Then allow only specific outbound traffic to allowed domains

iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT



# Explicitly REJECT all other outbound traffic for immediate feedback

iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited



echo "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 1

else

   echo "Firewall verification passed - unable to reach https://example.com as expected"

fi



# Verify GitHub API access

if ! 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 1

else

   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. 团队快速入职

新团队成员可在几分钟内获得完全配置的开发环境,所有必要的工具和设置都已预装。

3. 一致的 CI/CD 环境

在 CI/CD 流水线中镜像您的开发容器配置,确保开发和生产环境匹配。

相关资源

VS Code 开发容器文档

Bash 沙箱

设置配置

GitLab CI/CD 集成

Official Dev Containers Docs

devcontainers-contrib/features




热门文章
更多>