十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AutoAgent 自定义 Docker 沙箱指南:从镜像构建到安全执行环境配置

AutoAgent 自定义 Docker 沙箱指南:从镜像构建到安全执行环境配置 AutoAgent 自定义 Docker 沙箱指南从镜像构建到安全执行环境配置【免费下载链接】AutoAgentAutoAgent: Fully-Automated and Zero-Code LLM Agent Framework项目地址: https://gitcode.com/GitHub_Trending/au/AutoAgent本指南以官方文档《Comment Créer un Soutien Docker sur Mesure》自定义 Docker 沙箱指南为骨架结合 AutoAgent 仓库源码与运行时文档展开。默认的沙箱环境只预装精简的基础软件当代理任务需要 Node.js、Ruby 等额外运行时或特定系统依赖时你需要构建自己的 Docker 镜像并接入框架。读完本文你将掌握编写基于 Debian/Ubuntu 的自定义镜像、在config.toml中指定沙箱镜像、理解镜像首次构建与复用的底层机制以及解决 UID 冲突与端口占用两类常见故障。为什么需要自定义沙箱沙箱Sandbox是代理执行任务的地方。代理并不会直接在你的宿主机上运行命令这存在安全风险而是在 Docker 容器内运行。默认的 OpenHands 沙箱镜像python-nodejs:python3.12-nodejs22源自 nikolaik/python-nodejs预装了 Python、Node.js 等常用软件但你的用例可能还需要默认镜像中没有的软件——例如 Ruby、特定版本的编译器、系统级库等。从仓库的运行时文档 docs/i18n/zh-Hans/docusaurus-plugin-content-docs/current/usage/architecture/runtime.md 可以看到沙盒运行时存在的核心价值包括安全性不受信任的代码在隔离环境中执行无法访问或修改宿主系统资源一致性代码执行在不同机器与配置下保持一致消除在我机器上能跑的问题资源控制防止失控进程影响宿主机可重现性执行环境一致且可控便于复现错误。因此为沙箱预装任务所需的全部依赖是保证代理稳定高效执行的前提。你可以通过两种方式自定义沙箱直接使用一个已包含所需软件的现成镜像可跳过创建你的 Docker 镜像一节基于 Debian/Ubuntu 构建你自己的自定义镜像。创建你的自定义 Docker 镜像编写 Dockerfile要创建自定义镜像它必须基于 Debian官方文档明确要求基于 debian/ubuntu。例如若希望沙箱内具备node二进制可以编写如下 Dockerfile# 以最新的 ubuntu 为基础镜像 FROM ubuntu:latest # 执行必要的更新 RUN apt-get update apt-get install -y nodejs以 Ruby 为例同样可以这样写FROM debian:latest # 安装所需软件包 RUN apt-get update apt-get install -y ruby注意在本文描述的配置下OpenHands 将以用户openhands的身份在沙箱内运行因此通过 Dockerfile 安装的所有软件包应对系统上的所有用户可用而不仅是 root。上面的apt-get install安装的 nodejs/ruby 对全系统所有用户生效符合这一要求。构建镜像将上述内容保存为名为Dockerfile的文件放在一个独立目录中。然后在终端中导航到该目录并执行docker build -t custom-image .该命令会生成一个名为custom-image的新镜像并保存在本地 Docker Engine 中可供后续引用。在 config.toml 中指定自定义镜像OpenHands 的配置通过顶层文件config.toml完成。在 OpenHands 目录下创建或编辑config.toml写入以下内容[core] workspace_base./workspace run_as_openhandstrue sandbox_base_container_imagecustom-image其中各字段含义如下配置项说明workspace_base工作区的基础路径默认./workspace沙箱中挂载的宿主目录run_as_openhands是否以openhands用户身份运行布尔值默认truesandbox_base_container_image指定沙箱使用的基础镜像名称必须设置为上一步构建的自定义镜像名这里可以直接使用你本地构建的镜像名也可以使用已经拉取到本地的任意镜像。从配置文档 docs/i18n/zh-Hans/docusaurus-plugin-content-docs/current/usage/configuration-options.md 中可以看到run_as_openhands的默认值即为true即框架默认在沙箱内以非 root 用户执行任务。运行并验证在项目根目录执行make run启动后在浏览器中访问localhost:3001即可在界面中检查所需依赖是否可用。以 nodejs 示例为例在控制台执行node -v输出应为类似v18.19.1的版本号。若看到预期版本号说明自定义镜像已成功接入沙箱环境。技术原理解析镜像的首次构建与复用自定义镜像并非被直接使用OpenHands 会基于它派生出一个运行时镜像。整个流程可以概括为首次使用当某个自定义镜像第一次被使用且未找到对应的运行时镜像时框架会基于它执行一次构建后续复用构建完成后运行时镜像会被缓存并打上特殊标签之后的运行会直接命中缓存并返回无需重复构建。构建由_build_sandbox_image()完成它把你的自定义镜像作为基础FROM {base_image}随后注入 OpenHands 运行所需的系统组件与 conda 环境生成的 Dockerfile 内容示意如下dockerfile_content ( fFROM {base_image}\n RUN apt update apt install -y openssh-server wget sudo\n RUN mkdir -p -m0755 /var/run/sshd\n RUN mkdir -p /openhands mkdir -p /openhands/logs chmod 777 /openhands/logs\n RUN wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh\n RUN bash Miniforge3-$(uname)-$(uname -m).sh -b -p /openhands/miniforge3\n RUN bash -c . /openhands/miniforge3/etc/profile.d/conda.sh conda config --set changeps1 False conda config --append channels conda-forge\n RUN echo export PATH/openhands/miniforge3/bin:$PATH ~/.bashrc\n RUN echo export PATH/openhands/miniforge3/bin:$PATH /openhands/bash.bashrc\n ).strip()可以看到整个构建包含三个层次系统层安装openssh-server、wget、sudo并初始化 sshd 运行目录conda 层下载并安装 Miniforge3 到/openhands/miniforge3配置 conda-forge 频道环境层将 miniforge 的 bin 目录写入~/.bashrc与/openhands/bash.bashrc确保登录 shell 能直接使用 conda。此外镜像名称会通过_get_new_image_name()被改写后续运行查找的正是这个被改写后的名称——这正是首次构建、后续命中缓存机制的实现基础。三标签缓存体系从运行时文档 runtime.md 可知OpenHands 为运行时镜像维护了一套三标签缓存体系用于平衡可重现性与构建速度版本标签oh_v{openhands_version}_{base_image}最通用锁定标签oh_v{openhands_version}_{16_digit_lock_hash}哈希由基础镜像名、pyproject.toml与poetry.lock内容计算独立于源代码源码标签oh_v{openhands_version}_{lock_hash}_{source_hash}最具体哈希来自源码目录。构建时按源码标签 → 锁定标签 → 版本标签 → 从零构建的优先级查找可复用镜像从而在代码微小改动时快速重建、在完全一致时跳过构建大幅缩短启动时间。AutoAgent 源码视角沙箱环境与基础镜像管理虽然官方自定义沙箱指南以 OpenHands 的config.toml为配置入口但在 AutoAgent 仓库中沙箱运行时的底层实现同样值得关注它可以帮助你理解代理与 Docker 容器的实际交互方式。DockerEnv 与 DockerConfigAutoAgent 的沙箱执行环境由 autoagent/environment/docker_env.py 中的DockerEnv类实现其配置由DockerConfig数据类承载dataclass class DockerConfig: container_name: str # Docker 容器名称 workplace_name: str # 工作区目录名容器内挂载点 communication_port: int # 通信端口默认 12345 conda_path: str # 容器内 conda 路径如 /root/miniconda3 test_pull_name: str field(defaultmain) # 测试分支名 task_name: Optional[str] field(defaultNone) git_clone: bool field(defaultFalse) # 是否在容器内克隆 AutoAgent 仓库 setup_package: Optional[str] field(defaultNone) local_root: str field(defaultos.getcwd()) # 本地工作区根目录从源码结构看DockerEnv.init_container()完成容器生命周期的管理先检查同名容器是否已存在已运行则跳过、已停止则启动否则执行docker run创建新容器并将tcp_server.py复制到工作区、以--user root启动同时把本地工作区目录-v挂载进容器、映射通信端口-pdocker_command [ docker, run, -d, --name, self.container_name, --user, root, -v, f{self.local_workplace}:{self.docker_workplace}, -w, f{self.docker_workplace}, -p, f{self.communication_port}:{self.communication_port}, BASE_IMAGES, /bin/bash, -c, fpython3 {self.docker_workplace}/tcp_server.py --workplace {self.workplace_name} --conda_path {self.conda_path} --port {self.communication_port} ]容器启动后DockerEnv.run_command()通过 socket 连接容器内的tcp_server.py以 JSON 协议逐行收发命令与流式输出——这是代理在沙箱中执行命令的通信通道。同时with_env()装饰器将环境实例注入工具函数使各工具无需感知底层是 Docker 还是本地环境。基础镜像的自动选择AutoAgent 的基础镜像并非写死而是由 constant.py 统一管理BASE_IMAGES os.getenv(BASE_IMAGES, None) def get_architecture(): machine platform.machine().lower() if x86 in machine or amd64 in machine or i386 in machine: return tjbtech1/metachain:amd64_latest elif arm in machine: return tjbtech1/metachain:latest else: return tjbtech1/metachain:latest if BASE_IMAGES is None: BASE_IMAGES get_architecture()也就是说你可以通过环境变量BASE_IMAGES显式指定镜像若未设置框架会根据当前机器的 CPU 架构x86/amd64 或 arm自动选择预构建镜像。READMEREADME.md中也提到You dont need to manually pull the pre-built image, because we have let Auto-Deep-Research automatically pull the pre-built image based on your architecture of your machine. 即无需手动拉取镜像框架会按架构自动完成。这与官方自定义沙箱指南中手动指定sandbox_base_container_image的思路互补前者面向一键开箱后者面向深度定制。如果希望像官方指南那样完全掌控沙箱内容可以将BASE_IMAGES设为你自定义构建的镜像例如BASE_IMAGEScustom-image auto main故障排除错误useradd: UID 1000 is not unique现象控制台输出中出现useradd: UID 1000 is not unique。原因OpenHands 尝试在沙箱内以 UID 1000 创建openhands用户但该 UID 在自定义镜像中已被占用例如某些镜像预置了 uid 1000 的用户。解决在config.toml中修改sandbox_user_id为其他值[core] workspace_base./workspace run_as_openhandstrue sandbox_base_container_imagecustom-image sandbox_user_id1001端口被占用错误现象提示端口被占用或不可用。解决删除所有正在运行的 Docker 容器后重新执行。先通过docker ps查看当前容器再对相关容器执行docker rm container必要时先docker stop container最后重新运行make run。结合 AutoAgent 源码在 autoagent/environment/docker_env.py 中容器端口信息由check_container_ports()解析docker ps输出的端口映射如0.0.0.0:12345-12345/tcp并在wait_for_container_ready()中确认端口与tcp_server.py进程均就绪后才认为容器启动成功。因此端口冲突会直接导致沙箱初始化失败清理容器后重试是最直接的恢复手段。小结自定义 Docker 沙箱是让代理按需获得运行环境的标准化手段。整个流程可以概括为四步编写 Dockerfile基于 Debian/Ubuntu用apt-get安装任务所需软件注意软件需对所有用户可用构建镜像docker build -t 镜像名 .接入框架在config.toml的[core]段设置sandbox_base_container_imageAutoAgent 亦可直接通过环境变量BASE_IMAGES指定运行验证make run后在localhost:3001用node -v等命令确认依赖就绪。底层机制上OpenHands 会将自定义镜像二次构建为运行时镜像并通过三标签体系缓存复用AutoAgent 侧则由DockerEnv/DockerConfig管理容器生命周期、以 TCP 通道执行命令。遇到 UID 冲突修改sandbox_user_id遇到端口占用则清理 Docker 容器后重试。掌握了这些你就能为任意代理任务定制安全、可重现的执行环境。【免费下载链接】AutoAgentAutoAgent: Fully-Automated and Zero-Code LLM Agent Framework项目地址: https://gitcode.com/GitHub_Trending/au/AutoAgent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表