概览
envd 是 E2B 开发的沙箱内管理守护进程,用于支持健康检查、命令执行、文件读写等沙箱管理能力。本文介绍如何基于腾讯修改版 envd 构建 AGS 自定义沙箱镜像,并在 AGS 中创建、启动和调试沙箱。
envd 使用方式说明
腾讯修改版 envd 镜像地址如下:
版本 | 镜像地址 |
推荐使用 | ccr.ccs.tencentyun.com/ags-image/envd:v0.5.14 |
旧版本 | ccr.ccs.tencentyun.com/ags-image/envd:v0.2.11 |
在业务镜像 Dockerfile 中使用以下方式引入 envd:
COPY --from=ccr.ccs.tencentyun.com/ags-image/envd:v0.5.14 --chmod=755 /usr/bin/envd /usr/bin/envd
说明:
ccr.ccs.tencentyun.com/ags-image/envd:v0.5.14 仅用于提供 /usr/bin/envd 二进制文件。最终运行的镜像仍然是您的业务镜像。envd 默认监听
49983 端口。AGS 通过 envd 完成沙箱健康检查、命令执行等管理操作。容器内典型进程结构如下:
进程 | 端口 | 作用 |
/usr/bin/envd | 49983 | AGS 沙箱管理守护进程,提供健康探针、命令执行等能力。 |
业务进程 | 按业务配置 | 对外提供业务服务,例如 Web 服务、Agent 服务、Notebook 服务等。 |
envd 使用限制与版本差异
通用限制
最终业务镜像必须包含
/usr/bin/envd,且该文件需要具备可执行权限。envd 默认监听
49983 端口;AGS 侧健康检查和管理流量需要能访问该端口。如果按本文推荐方式使用
/bin/bash -l -c 同时启动 envd 和业务进程,最终业务镜像内必须存在 /bin/bash。精简镜像、distroless 镜像、scratch 镜像通常默认不包含 bash,需要额外安装或改用镜像内实际存在的 shell。envd 的命令执行和文件接口都会按用户身份运行或解析路径。被使用的用户必须能被系统用户库查到,即通常需要存在于
/etc/passwd 中,并且 UID/GID 必须是可解析的数字。相对路径会按用户 home 目录解析;
~ 支持解析为当前用户 home,但不支持 ~otheruser 这种指定其他用户 home 的写法。命令执行时,工作目录必须已经存在;如果 cwd 解析后的目录不存在,命令会启动失败。
文件上传、创建目录、组合文件等操作会创建父目录并尝试 chown 到目标用户。建议让 envd 以 root 运行;如果以非 root 运行,涉及 chown 或写入受限目录的操作可能失败。
命令执行时只继承 envd 当前环境里的 PATH,并额外设置 HOME、USER、LOGNAME 以及
/init 注入的环境变量。镜像需要确保 PATH 能找到业务命令,或在 SDK/调用侧使用绝对路径。进程信号接口只支持 SIGTERM 和 SIGKILL。
v0.2.11 限制
SDK 命令执行会直接执行请求里的 cmd 和 args,不会自动包一层 shell。因此
echo hello 这类简单命令可以直接执行,但管道、重定向、&&、通配符等 shell 语法需要显式使用 /bin/bash -lc 或 /bin/sh -c(E2B SDK 会自动附加 /bin/bash -lc)。v0.2.11 的命令执行本身不强制依赖
/bin/sh 或 /usr/bin/nice;但如果启动沙箱时采用本文的 /bin/bash -l -c 模板,仍然需要 /bin/bash。命令启动后 envd 会尝试写
/proc/<pid>/oom_score_adj。写入失败只会打印错误,不会阻止命令继续运行;但镜像/运行环境需要有正常的 /proc 才能获得完整行为。文件下载和上传接口要求传入 username,源码中的 OpenAPI 约束示例是 root 或 user。实际能否使用取决于镜像内是否存在该用户。
/files 上传只支持 multipart/form-data,不支持 application/octet-stream 原始 body 上传,也不支持 gzip 压缩请求体。文件上传请求体的 Content-Encoding 只支持 gzip 或 identity;其他编码会返回错误。文件下载的 Accept-Encoding 支持 gzip 或 identity,Range/条件请求会退回 identity,如果客户端拒绝 identity 会返回 406。
v0.2.11 的
/init 只设置环境变量。v0.5.14 限制
SDK 命令执行会被 envd 包装成
/bin/sh -c 'echo 100 > /proc/$$/oom_score_adj && exec /usr/bin/nice ...'。因此最终镜像必须包含 /bin/sh 和 /usr/bin/nice,并且 /proc/$$/oom_score_adj 需要可写;否则 SDK 命令可能无法真正启动业务命令。envd
-cmd 启动参数会使用 /bin/bash -l -c 执行启动命令,并且工作目录固定为 /home/user。如果使用 -cmd,镜像必须包含 /bin/bash,且 /home/user 必须存在。v0.5.14 默认用户是 root,也可以通过
/init 的 defaultUser 设置默认用户;无论使用默认用户还是显式 username,目标用户都必须存在于镜像内。v0.5.14 支持通过
/init 设置 defaultWorkdir。未设置时,相对路径仍按用户 home 目录解析;设置后,命令和文件接口的默认工作目录/默认路径会受该值影响。文件上传支持 multipart/form-data 和 application/octet-stream。使用 application/octet-stream 时必须提供 path 查询参数。
前置准备
工具依赖
工具 | 用途 |
Docker | 构建和推送镜像 |
腾讯云容器镜像服务 CCR 或 TCR | 存储自定义镜像 |
腾讯云 CAM | 创建拉取镜像所需角色 |
构建自定义镜像
基础 Dockerfile
以下示例演示如何在业务镜像中引入 envd。
FROM ubuntu:22.04COPY --from=ccr.ccs.tencentyun.com/ags-image/envd:v0.5.14 --chmod=755 /usr/bin/envd /usr/bin/envdRUN apt-get update && apt-get install -y \\bash \\curl \\ca-certificates \\python3 \\python3-pip \\&& rm -rf /var/lib/apt/lists/*RUN pip3 install --no-cache-dir requests pandas numpyUSER root
说明:
COPY --from=... /usr/bin/envd /usr/bin/envd 用于从腾讯修改版 envd 镜像中拷贝 envd。--chmod=755 用于确保 envd 在最终镜像内具备可执行权限。最终镜像可根据业务需要安装 Python、Node.js、Java、Go 等运行环境。
如果 envd 需要以 root 用户身份执行命令,需要以 root 启动。
登录镜像仓库
以 CCR 为例,执行以下命令登录镜像仓库:
docker login ccr.ccs.tencentyun.com
带业务服务的 Dockerfile 示例
如果您的沙箱需要同时运行 envd 和业务服务,可将业务服务也打包到同一个镜像中。
FROM node:20-bookwormCOPY --from=ccr.ccs.tencentyun.com/ags-image/envd:v0.5.14 --chmod=755 /usr/bin/envd /usr/bin/envdWORKDIR /appCOPY package.json package-lock.json ./RUN npm ci --omit=devCOPY . .EXPOSE 8080
注意:
AGS 运行沙箱时会以沙箱工具配置中的启动命令和启动参数为准。即使镜像中配置了 CMD 或 ENTRYPOINT,也建议在 AGS 控制台中显式填写启动命令和参数。
构建镜像
AGS 运行环境建议使用 linux/amd64 架构。构建镜像时请指定平台:
docker build \\--platform=linux/amd64 \\-t ccr.ccs.tencentyun.com/your-namespace/your-sandbox:latest \\.
Apple Silicon Mac 用户也建议显式指定
--platform=linux/amd64,避免构建出 arm64 镜像导致沙箱运行失败。推送镜像
执行以下命令推送镜像:
docker push ccr.ccs.tencentyun.com/your-namespace/your-sandbox:latest
推送完成后,记录完整镜像地址,例如
ccr.ccs.tencentyun.com/your-namespace/your-sandbox:latest。后续创建 AGS 沙箱工具时需要填写该镜像地址。创建沙箱工具
基本配置
在 AGS 控制台创建沙箱工具时,填写以下配置:
配置项 | 示例值 | 说明 |
工具名称 | my-envd-sandbox | 自定义名称 |
工具类型 | 自定义镜像 | 使用自定义镜像 |
镜像地址 | ccr.ccs.tencentyun.com/your-namespace/your-sandbox:latest | 第四步推送的镜像 |
镜像仓库类型 | 个人版或企业版 | 根据 CCR 账号类型选择 |
CAM 角色 | ags-ccr-full | 具备镜像拉取权限 |
CPU | 2 核 | 可按业务调整 |
内存 | 2 GiB | 可按业务调整 |
网络策略 | 公网 | 按业务访问需求配置 |
启动命令配置
AGS 运行沙箱时建议显式配置启动命令和启动参数。
仅启动 envd
如果镜像只需要提供基础沙箱命令执行、文件读写能力,可直接启动 envd。
配置项 | 值 |
启动命令 | /usr/bin/envd |
启动参数 | 留空 |
同时启动 envd 和业务进程
如果镜像内还需要启动业务服务,推荐使用
/bin/bash -l -c,先后台启动 envd,再启动业务进程。配置项 | 值 |
启动命令 | /bin/bash |
启动参数第 1 项 | -l |
启动参数第 2 项 | -c |
启动参数第 3 项 | /usr/bin/envd > /tmp/envd.log 2>&1 & exec your-business-command |
例如,启动一个监听 8080 端口的 Node.js 服务:
/usr/bin/envd > /tmp/envd.log 2>&1 & exec node /app/server.js
如果业务进程需要自动重启,可参考 OpenClaw cookbook 的方式:
/usr/bin/envd > /tmp/envd.log 2>&1 & while true; do node /app/server.js; echo '[restart]'; sleep 1; done
注意:
envd 必须启动,否则 AGS 无法正常执行健康检查和沙箱管理操作。
启动参数需要按项填写,每个参数单独一个输入框。
不要将
-l -c "..." 合并到同一个参数输入框中。端口配置
至少需要配置 envd 端口:
名称 | 协议 | 端口 | 说明 |
envd | TCP | 49983 | envd 管理端口 |
如果业务服务也需要被访问,请额外暴露业务端口。例如:
名称 | 协议 | 端口 | 说明 |
app | TCP | 8080 | 业务服务端口 |
健康检查配置
推荐使用 envd 的健康检查接口:
配置项 | 示例值 | 说明 |
探针路径 | /health | envd 健康检查路径 |
探针端口 | 49983 | envd 管理端口 |
就绪超时 | 30000 ms | - |
探针周期 | 3000 ms | - |
失败阈值 | 100 | - |
启动沙箱并验证
创建沙箱实例
在 AGS 控制台中选择刚创建的沙箱工具,创建沙箱实例。等待实例状态变为 Running。
验证 envd 进程
可通过 AGS 登录沙箱后执行:
ps aux | grep envd | grep -v grep
预期可以看到
/usr/bin/envd 进程。或只查看 envd 和业务进程:ps aux | grep -E 'envd|node|python|java' | grep -v grep
查看端口监听:
ss -lntp
预期可以看到 49983 端口处于监听状态。
验证健康检查
在沙箱内执行:
curl -s http://127.0.0.1:49983/health
说明:
健康检查通过后,沙箱实例才会进入可用状态。
如果返回正常,说明 envd 已启动并监听 49983 端口。
验证命令执行能力
如果使用 SDK 调用沙箱,可以执行简单命令验证:
const result = await sandbox.commands.run('echo hello envd')console.log(result.stdout)
也可以验证文件读写:
await sandbox.files.write('/workspace/hello.txt', 'hello envd')const content = await sandbox.files.read('/workspace/hello.txt')console.log(content)
日志与调试
查看 envd 日志
如果启动命令中将 envd 日志输出到了
/tmp/envd.log:cat /tmp/envd.log
查看进程状态
ps aux
常见问题
1. 为什么不能直接把 envd 镜像作为业务镜像?
envd 镜像的主要作用是提供 AGS 沙箱管理守护进程
/usr/bin/envd。实际业务通常还需要自己的运行环境、依赖和服务进程。因此推荐通过 Dockerfile 的多阶段构建,将 envd 拷贝进业务镜像中。推荐写法:
COPY --from=ccr.ccs.tencentyun.com/ags-image/envd:v0.5.14 --chmod=755 /usr/bin/envd /usr/bin/envd
2. 沙箱一直无法 Running 怎么排查?
请检查以下配置:
1. 镜像是否为 linux/amd64 架构。
2. 镜像地址是否正确,AGS 角色是否具备拉取镜像权限。
3. 启动命令是否正确。
4.
/usr/bin/envd 是否存在且有执行权限。5. envd 是否监听 49983 端口。
6. 健康检查是否配置为
/health 和 49983 端口。7. 启动命令中业务进程是否过早退出。
8. 如果使用
/bin/bash -l -c 启动模板,镜像内是否存在 /bin/bash。3. 为什么 SDK 命令执行失败?
可能原因包括:
1. envd 未启动。
2. 49983 端口未配置。
3. 健康检查未通过。
4. 沙箱实例尚未进入 Running 状态。
5. 启动命令覆盖或遗漏了 envd 启动逻辑。
6. v0.5.14 镜像内是否存在
/bin/sh 和 /usr/bin/nice,以及 /proc 是否可写入 oom_score_adj。7. 命令使用的用户、工作目录、PATH 是否正确;目标用户必须存在,cwd 必须已存在。
4. 启动参数应该怎么填?
如果使用
/bin/bash -l -c 方式,启动参数需要分三项填写:-l-c/usr/bin/envd > /tmp/envd.log 2>&1 & exec your-business-command
不要写成一项:
-l -c "/usr/bin/envd > /tmp/envd.log 2>&1 & exec your-business-command"
5. 如何选择 envd 版本?
推荐优先使用:
ccr.ccs.tencentyun.com/ags-image/envd:v0.5.14
如业务已依赖旧版本行为,可使用:
ccr.ccs.tencentyun.com/ags-image/envd:v0.2.11
6. envd 可以使用非 root 用户启动吗?有哪些限制?
如果以非 root 用户启动,envd 会有如下表现:
1. 健康检查可以正常使用。
2. Process.Start 会按请求中的 username 设置子进程 UID/GID,username 与 envd 启动用户相同时可以执行,指定 root 或其他 UID 时,通常会报
fork/exec: operation not permitted。3. GET /files 不会切换到 username 对应的系统身份。username 主要用于查找用户和解析 home 路径,文件最终仍由 envd 的启动用户读取。因此能否读取取决于该用户的 Unix 文件权限。
4. POST /files 会先以 envd 启动用户创建文件或父目录,再 chown 到 username 对应的 UID/GID。目标用户与 envd 启动用户相同时通常可用;指定 root 或其他用户时通常会因 chown 权限不足返回 500。
5. 上传不是原子操作:文件可能已经被创建或截断后,才在 chown 阶段失败,因此失败后可能留下空文件,或导致原文件内容被清空。
6. username 对应的系统用户必须存在,用户 home、cwd 和目标目录也必须对 envd 启动用户可访问。
推荐的非 root 配置:
7. 在镜像中创建固定用户,例如
user,并确保 /etc/passwd 中存在该用户。8. 以
user 启动 envd,SDK 命令和文件接口也始终使用 user。9. 确保 home、工作目录和业务文件均归
user 所有且权限正确。10. 不要尝试通过该 envd 执行 root/其他用户命令,也不要上传需要归 root/其他用户所有的文件。