Skip to content

命令、文件与终端

从任意镜像创建沙箱、运行命令并读取输出、读写文件,以及终端。

更新于

创建沙箱

POST /v1/sandboxes 创建一个沙箱;每个字段都可以省略。

字段 说明
image 任意 OCI 镜像,公开或私有都可以(python:3.12、ghcr.io/acme/api:1.4)。不指定时,使用平台的默认镜像(见下文)。
image_pull_secret 用于私有镜像:一个机密的名称,它的值是镜像仓库的 username:password。它只用于拉取镜像,沙箱里不会有它。
snapshot 或 template 从快照或模板启动,而不是从镜像。三者最多给出一个。
name 1 到 63 个小写字母、数字和连字符。凡是接受 id 的地方,也接受名称。
env, metadata 环境变量(合计最多 256 KiB);最多 64 个标签,用量可以按标签分组。标签 product 归平台使用,设置它的创建或修改会被拒绝 (400 reserved_metadata)。
limits 规格:{vcpus, memory_bytes},内存必须是偶数 MiB(即机器内存加载时所用的 2 MiB 页的整数倍),至少 128 MiB,且不超过你的套餐允许的大小。其他内存值会被拒绝 (400 invalid_field)。
sleep_after_seconds 空闲时保持运行多久(秒):默认 30,最少 1,null 表示永不休眠。参见休眠与唤醒。
sleep_notice_ms, sleep_hold_max_ms 休眠前多久通知它的程序,以及程序最多能自行让它保持运行多久:参见从内部保持运行。
expires_at, delete_after_idle_ms 何时删除;或者休眠多久之后删除。
volumes, drives, public_ports, egress 挂载到各路径上的云盘和存储卷、任何人都能打开的端口、它的网络规则。设置了 copy: true 的新存储卷,第一次挂载时会得到镜像在该路径下的内容,和 Docker 对新命名卷的做法一样。
start_command, start, ready 机器启动时运行的服务,以及判断它已启动的检查(见下文)。
init "systemd":完整的系统,镜像自己的 systemd 作为 PID 1(见下文)。不设置时,使用平台的 init。
runtime 进程的限制、内核参数、内存中的文件系统、解析器以及 /dev/shm 的大小,与应用版本的运行时设置相同。不设置时,打开文件数为 1,024,最多可提高到 524,288,与 Docker 下相同。
awake_ports, connection_idle_seconds 哪些端口上经由链接升级的连接 (WebSocket) 在打开期间让它保持运行,以及这样的连接在没有任何数据多久之后被关闭:参见有客户端连接时保持运行。
hostname, stop 机器永久使用的名称,用来代替它的 id;重启或删除之前如何停止它的服务:{signal, grace_ms}(镜像的 STOPSIGNAL,没有时为 SIGTERM;默认 10 秒后强制结束,最长十分钟)。
project_network true:在它运行任何东西之前,就把它加入项目的私有网络,地址为它的 project_address。
checkpoint {every_seconds}:在它运行期间创建检查点,这样机器丢失时它能带着进程继续运行。默认不创建。
region na、eu 或 ap:在哪里创建。不指定时,为控制平面所在的区域。参见区域。

从某个镜像创建的第一个沙箱,在平台拉取镜像并保存其模板期间处于 starting;发给它的调用会等到它就绪。之后从该镜像创建的每个沙箱都是模板的副本,取自一个已在运行的副本池。

不指定 limits 时,沙箱的规格与机器的基础模板相同,并且不会超过你的套餐允许的最大规格:免费版为 2 vCPU 和 4 GiB,付费版为 8 vCPU 和 16 GiB。limits 超过套餐允许的上限会被拒绝 (403 plan_size_exceeded)。沙箱的根磁盘为 8 GiB。

默认镜像

Debian 12,带 Node 24、Python 3.11(pip、venv、uv)、Go、Rust、带 Maven 的 Java 25,以及常用工具(ripgrep、jq、sqlite3、rsync、dig、sudo)。命令以 root 身份在 /root 中运行;第二个账户 user 无需密码即可使用 sudo。镜像中不启动任何东西,也没有端口在监听。

随机器启动的服务

给出 start_command(或 start: true,运行镜像自己的 ENTRYPOINT 和 CMD)和 ready 检查时,平台会启动服务一次,等它就绪,然后把这个状态保存为模板。用相同设置创建的每个沙箱都是它的副本,服务已经在运行,内存在沙箱改动之前都是共享的。

程序在模板保存之前做的事,在从它创建的每个沙箱中都一模一样:密钥、令牌、Cookie、它生成的 id、随机数生成器的状态。启动命令在就绪之前不能生成任何标识用户或会话的东西;请在第一次使用时生成,或在沙箱创建后运行的命令中生成。

完整的系统:systemd

设置 init: "systemd" 后,沙箱就是一台完整的机器:镜像自己的 systemd 作为 PID 1,平台的代理程序是它的一个服务。你可以像在服务器上一样安装软件包、用 systemctl 启动服务、使用 cron 和 journal,以及通过 SSH 登录。

glac sandboxes create --name box --init systemd
glac sandboxes exec box -- systemctl status
  • 不指定镜像时,使用平台的 Ubuntu 24.04(见下文)。任何带 systemd 的镜像都可以;不带 systemd 的镜像会构建失败 (invalid_image)。
  • 运行什么由它的 unit 决定。同时给出 init 和 start、start_command 或 ready 的创建请求会被拒绝 (400 invalid_start);从快照或模板创建的沙箱设置 init 也会被拒绝,因为它沿用来源的设置。其他值返回 400 invalid_field。POST /v1/run 也接受 init,沙箱会说明自己的 init(init:systemd,或为 null 表示平台的 init)。
  • 自己的 machine ID。/etc/machine-id(以及 D-Bus 的副本)属于沙箱自己,在它的机器创建时生成,在休眠、唤醒和迁移后保持不变;从它的快照创建的沙箱,以及每个分叉,都有各自的 machine ID。它的 journal 按这个 ID 保存在它的磁盘上。
  • 平台负责网络、解析器、时钟和串行控制台:会改动它们的 unit(systemd-networkd、NetworkManager、systemd-resolved、timesyncd、chrony、串行控制台上的 getty、systemd-firstboot)在每次启动时都会被屏蔽。镜像的 /etc/systemd/system 中同名的 unit 会覆盖这个屏蔽,就像它会覆盖任何 unit 一样。
  • 休眠。它和任何沙箱一样,空闲时休眠:systemd 自己的定时器不会让它保持运行,设置了 Persistent=true 的 timer unit 会在沙箱醒来时补跑错过的任务。cron 只在沙箱运行时执行,它每分钟一次的运行最多会把休眠推迟一分钟;必须按计划运行的任务,请用 timer unit。
  • 经由平台运行的命令(exec、run、终端)是代理程序服务的进程,不是登录会话:systemctl --user 在通过 SSH 登录机器自己的服务器时可用,在这里则不行。沙箱的 env 和 secret_env 是这些命令的环境;systemd 的服务只有它们的 unit 给出的环境 (Environment=)。
  • reboot 和 poweroff 会结束机器,和任何沙箱一样。

平台的 Ubuntu 镜像是 Ubuntu 24.04,带 systemd、D-Bus、OpenSSH 服务器、cron,以及人或智能体最先会用到的工具(curl、git、jq、带 venv 的 python3、rsync、sudo、htop、dig、zip 等);其他工具用 apt 安装。命令以 root 身份运行,账户 user 无需密码即可使用 sudo。它的 SSH 服务器只接受密钥登录,每台机器在服务器第一次启动时生成自己的主机密钥;从外部访问沙箱要经过平台的 SSH 网关,机器自己的服务器供它旁边的东西使用(转发到它的端口、项目网络上的另一个沙箱)。那些每天唤醒它、却与你无关的定时器(apt 的、motd-news、fstrim、dpkg 的备份)都已屏蔽,它的 journal 保存在它的磁盘上。

运行命令

调用 作用
POST /v1/sandboxes/{id}/run 运行一条命令并等待它完成。返回退出码、stdout 和 stderr。
POST /v1/sandboxes/{id}/exec 启动一条命令并立即返回它的 id (exe-…)。用 GET …/exec/{exec}/output 读取它的输出,也可以持续跟随。
POST /v1/run 创建一个沙箱,运行一条命令,然后删除它:沙箱只存在于这个请求期间。

以字符串给出的命令由 sh -c 运行;以列表给出的命令按原样运行,不经过 shell,程序按命令自身环境的 PATH(镜像的,加上调用添加的)查找,与 sh -c 的查找方式相同,所以只有镜像才添加的目录(/usr/local/cargo/bin、/opt/conda/bin)中的程序也能找到。默认以 root 身份运行,可以用 user 指定其他用户,工作目录为 cwd,env 会添加到沙箱的环境变量中。

glac sandboxes exec web 'ls /srv | wc -l'           # one argument: a line for sh -c
glac sandboxes exec web -- ls -la /srv              # several: a program and its arguments
tar c . | glac sandboxes exec web tar x -C /srv     # standard input goes to the command
cmd=$(glac sandboxes exec web --detach -- sh -c 'while true; do date; sleep 1; done')
glac sandboxes logs web "$cmd"                      # what it printed so far (--follow: until it ends)
glac sandboxes kill web "$cmd" --signal INT
  • 输出为每个字节都记了位置,每条命令保留最后 16 MiB,所以被中断的读取方可以从上次停下的地方继续。命令从不等待读得慢的读取方:大量输出请写到文件里,再复制出来。
  • 命令属于沙箱,不属于连接:连接断开后,glac sandboxes exec 会从上次停下的地方继续;第一次 Ctrl-C 发给命令(第二次则离开,让命令继续运行)。
  • 退出码。glac run、glac sandboxes exec 和 glac sandboxes shell 以命令的退出码退出,失败的不是命令本身时以 125 退出。SDK 把退出码作为结果返回,而不是作为错误。

文件

/v1/sandboxes/{id}/files 以运行命令的用户(或用 user 指定的其他用户)的身份读取、写入、列出、移动和删除文件,还可以设置文件的权限、长度或最后修改时间(PATCH 带上 mode、size_bytes、modified_at;SDK 中为 set_attributes)。写入会一次替换整个文件,除非给出 offset;读取方看到的要么是旧内容,要么是新内容,内容中途断掉的写入会让文件保持原样。任意长度的文件都可以在一次调用中读写:字节边来边传,途中没有任何东西会持有整个文件,读取时会先给出长度。SDK 的 upload、download 和 read_stream (readStream) 可以在本地文件和沙箱之间传输。

glac sandboxes cp -r ./src web:/srv/src              # in
glac sandboxes cp web:/var/log/app.log .             # out
glac sandboxes cp web:/etc/os-release -              # to standard output
sbx.files.write("/srv/config.json", '{"debug": true}')   # makes the directories above it
print(sbx.files.list("/srv"))
data = sbx.files.read("/srv/config.json")

终端

glac sandboxes shell web 打开一个终端:shell,或给出的命令 (glac sandboxes shell web htop)。按 Enter,再按 ~.,就会离开并让它继续运行;--join exe-… 回到这个终端。打开着的终端不会让沙箱保持运行:沙箱休眠后,按下一个键就会唤醒它。

在 API 中,终端是一条以 tty: {cols, rows} 启动的命令 (POST …/exec),加上一个到 …/exec/{exec}/tty 的 WebSocket,它承载终端的输入、输出和窗口大小。浏览器不能给 WebSocket 设置请求头,所以要在 ?sandbox_token= 中传一个带 tty 权限范围的令牌。控制台的终端就是这样工作的。SDK 中有 sbx.terminal()。

代码解释器、智能体与桌面

平台为有状态的代码执行、编程智能体,以及程序可以查看和操控屏幕的桌面准备了镜像。SDK 为它们提供了调用:Python 中为 sbx.run_code(…)、sbx.agent("claude") 和 Desktop(sbx)。参见 Python SDK 页面。

导航

输入以搜索……

↑↓ 切换↵ 选择Esc 关闭