Moby Engine API v1.19:容器/镜像/Exec 全端点参考与流式劫持协议深度解析
本文以 api/docs/v1.19.md 这份 Engine API v1.19 官方参考文档为主体,系统梳理该版本对外暴露的全部 REST 端点——容器、镜像、Exec 三大类接口的请求格式、查询参数、JSON 字段与状态码语义——并结合 moby 仓库当前源码(api/pkg/stdcopy/stdcopy.go、client/hijack.go、daemon/server/router/container/container_routes.go 等)印证其底层实现,帮助你既能按 v1.19 规范手写客户端调用,也能理解 attach、logs 等流式接口背后的连接劫持(hijacking)与 8 字节帧协议。
1. 概述:v1.19 与守护进程的通信约定
v1.19 参考文档开篇给出了四条基本约定,这也是编写任何 Engine API 客户端的起点:
- 默认监听地址:守护进程监听
unix:///var/run/docker.sock,可通过dockerd的绑定选项改到其他 host/port 或 Unix socket。 - REST 为主,流式例外:API 大体是 REST 风格,但对于
attach、pull等复杂命令,HTTP 连接会被"劫持"(hijack),用于在同一连接上双向传输stdout、stdin、stderr。 - Content-Length 要求:期望携带请求体的
POST请求应当带有Content-Length头。 - 版本前缀机制:URL 前缀指定要锁定的 API 版本,例如
/v1.18/info;若 URL 中不带版本号,则使用守护进程支持的最大 API 版本;若指定的版本不被支持,守护进程返回 HTTP400 Bad Request。
从当前仓库源码结构看,这一版本协商机制仍然保留:路由注册时会为每条路由同时挂上"带版本前缀"与"不带版本前缀"两条路径(见 daemon/server/server.go 中 CreateMux 对 versionMatcher 前缀的处理)。
版本适用前提:需要特别注意的是,当前仓库中的 daemon 已不再支持 1.24 之前的 API 版本——daemon/server/server.go 的注释明确写道"we no longer support API versions older than 1.24"。因此 v1.19 是一份历史版本参考,用于理解早期客户端(如 2015 年前后的 docker CLI)如何与守护进程交互;若你要对接现代 daemon,应以 api/docs/ 目录下较新的版本文档为准,但 v1.19 中定义的绝大多数端点形态、状态码与流式协议至今仍是现代版本的基础。
2. 容器端点(2.1 Containers)
2.1 列出容器:GET /containers/json
示例请求:
GET /v1.19/containers/json?all=1&before=8dfafdbc3a40&size=1 HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"Id": "8dfafdbc3a40",
"Names":["/boring_feynman"],
"Image": "ubuntu:latest",
"Command": "echo 1",
"Created": 1367854155,
"Status": "Exit 0",
"Ports": [{"PrivatePort": 2222, "PublicPort": 3333, "Type": "tcp"}],
"Labels": {
"com.example.vendor": "Acme",
"com.example.license": "GPL",
"com.example.version": "1.0"
},
"SizeRw": 12288,
"SizeRootFs": 0
},
{
"Id": "9cd87474be90",
"Names":["/coolName"],
"Image": "ubuntu:latest",
"Command": "echo 222222",
"Created": 1367854155,
"Status": "Exit 0",
"Ports": [],
"Labels": {},
"SizeRw": 12288,
"SizeRootFs": 0
}
]
(原文档示例还包含 sleepy_dog、running_cat 两个 echo 容器条目,字段结构相同。)
查询参数:
| 参数 | 说明 |
|---|---|
all |
1/True/true 或 0/False/false,是否显示全部容器。默认只显示运行中的容器(默认 false)。 |
limit |
只显示最近创建的 limit 个容器,包含非运行中的。 |
since |
只显示在指定 Id 之后创建的容器,包含非运行中的。 |
before |
只显示在指定 Id 之前创建的容器,包含非运行中的。 |
size |
1/True/true 或 0/False/false,是否显示容器尺寸(对应响应中 SizeRw/SizeRootFs)。 |
filters |
JSON 编码的 map[string][]string 过滤条件。可用过滤器:exited=<int>(退出码匹配)、`status=(restarting |
状态码:200 无错误;400 参数错误;500 服务端错误。
从源码看,该端点的服务端处理就是先解析表单、再从 filters 参数构造过滤器,最后按 all/size/limit 选项委托给后端 Containers 方法(见 daemon/server/router/container/container_routes.go 的 getContainersJSON),并且会按客户端声明的 API 版本裁剪响应字段——这一"按版本降级响应"的做法在 v1.19 时代就已存在。
2.2 创建容器:POST /containers/create
这是 v1.19 中参数最多的端点。示例请求:
POST /v1.19/containers/create HTTP/1.1
Content-Type: application/json
Content-Length: 12345
{
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"FOO=bar",
"BAZ=quux"
],
"Cmd": [
"date"
],
"Entrypoint": null,
"Image": "ubuntu",
"Labels": {
"com.example.vendor": "Acme",
"com.example.license": "GPL",
"com.example.version": "1.0"
},
"Volumes": {
"/volumes/data": {}
},
"WorkingDir": "",
"NetworkDisabled": false,
"MacAddress": "12:34:56:78:9a:bc",
"ExposedPorts": {
"22/tcp": {}
},
"HostConfig": {
"Binds": ["/tmp:/tmp"],
"Links": ["redis3:redis"],
"LxcConf": {"lxc.utsname":"docker"},
"Memory": 0,
"MemorySwap": 0,
"CpuShares": 512,
"CpuPeriod": 100000,
"CpuQuota": 50000,
"CpusetCpus": "0,1",
"CpusetMems": "0,1",
"BlkioWeight": 300,
"OomKillDisable": false,
"PidMode": "",
"PortBindings": { "22/tcp": [{ "HostPort": "11022" }] },
"PublishAllPorts": false,
"Privileged": false,
"ReadonlyRootfs": false,
"Dns": ["8.8.8.8"],
"DnsSearch": [""],
"ExtraHosts": null,
"VolumesFrom": ["parent", "other:ro"],
"CapAdd": ["NET_ADMIN"],
"CapDrop": ["MKNOD"],
"RestartPolicy": { "Name": "", "MaximumRetryCount": 0 },
"NetworkMode": "bridge",
"Devices": [],
"Ulimits": [{}],
"LogConfig": { "Type": "json-file", "Config": {} },
"SecurityOpt": [],
"CgroupParent": ""
}
}
示例响应:
HTTP/1.1 201 Created
Content-Type: application/json
{
"Id":"e90e34656806",
"Warnings":[]
}
顶层 JSON 参数(容器配置部分):
| 字段 | 类型 | 说明 |
|---|---|---|
Hostname |
string | 容器使用的 hostname。 |
Domainname |
string | 容器使用的 domain name。 |
User |
string | 容器内运行进程的用户。 |
AttachStdin / AttachStdout / AttachStderr |
bool | 是否附着到对应标准流。 |
Tty |
bool | 是否将标准流接到一个 tty(stdin 未关闭时包含 stdin)。 |
OpenStdin |
bool | 是否打开 stdin。 |
StdinOnce |
bool | 当唯一附着客户端断开后关闭 stdin。 |
Env |
string[] | 环境变量列表,形如 ["VAR=value", ...]。 |
Cmd |
string 或 string[] | 要运行的命令。 |
Entrypoint |
string 或 string[] | 容器的入口点。 |
Image |
string | 要使用的镜像名。 |
Labels |
map | 容器标签,{"key":"value", ...}。 |
Volumes |
map | 容器内挂载点路径到空对象的映射。 |
WorkingDir |
string | 命令运行的工作目录。 |
NetworkDisabled |
bool | 为 true 时禁用容器网络。 |
ExposedPorts |
map | 端口映射对象,形如 {"<port>/<tcp|udp>: {}}。 |
HostConfig |
object | 见下方。 |
HostConfig 字段:
| 字段 | 说明 |
|---|---|
Binds |
绑定挂载列表,两种形式:host-src:container-dest(两端必须为绝对路径)、host-src:container-dest:ro(容器内只读)。 |
Links |
链接列表,每项形如 container_name:alias。 |
LxcConf |
LXC 专用配置,仅在 lxc 执行驱动下生效。 |
Memory |
内存限制(字节)。 |
MemorySwap |
内存+swap 总限制;-1 表示无限制 swap。必须与 Memory 同时使用且 swap 值大于 memory。 |
CpuShares |
CPU 相对权重(相对其他容器的权重)。 |
CpuPeriod |
CPU 周期长度(微秒)。 |
CpuQuota |
每个周期内容器可用的 CPU 微秒数。 |
CpusetCpus |
允许执行的 CPU 集合(cgroups CpusetCpus)。 |
CpusetMems |
允许执行的内存节点(如 0-3、0,1),仅在 NUMA 系统上有效。 |
BlkioWeight |
块 IO 相对权重,取值 10–1000。 |
OomKillDisable |
是否禁用该容器的 OOM Killer。 |
PidMode |
PID 命名空间模式:container:<name|id> 或 host。 |
PortBindings |
端口绑定,形如 { "<port>/<protocol>": [{ "HostPort": "<port>" }] };注意端口是字符串而非整数。 |
PublishAllPorts |
为所有暴露端口分配临时宿主端口(布尔值)。端口在容器停止时释放、启动时分配,重启后可能变化;临时端口取自内核 ephemeral 区间,Linux 上由 /proc/sys/net/ipv4/ip_local_port_range 决定。 |
Privileged |
赋予容器对宿主的完全访问权限。 |
ReadonlyRootfs |
将容器根文件系统挂载为只读。 |
Dns / DnsSearch |
容器使用的 DNS 服务器列表 / DNS 搜索域列表。 |
ExtraHosts |
追加到容器 /etc/hosts 的主机名/IP 映射,形如 ["hostname:IP"]。 |
VolumesFrom |
从其他容器继承的卷,形如 <container name>[:<ro|rw>]。 |
CapAdd / CapDrop |
添加/移除的内核能力列表。 |
RestartPolicy |
容器退出后的行为。Name 为 "always"(总是重启)或 "on-failure"(仅退出码非零时重启,此时 MaximumRetryCount 控制重试次数)。默认为不重启。每次重启前附加递增延迟(自 100ms 起翻倍)以防止刷新服务端。 |
NetworkMode |
网络模式:bridge、host、none、container:<name|id>。 |
Devices |
设备列表,形如 { "PathOnHost": "/dev/deviceName", "PathInContainer": "/dev/deviceName", "CgroupPermissions": "mrw"}。 |
Ulimits |
ulimit 列表,形如 { "Name": "nofile", "Soft": 1024, "Hard": 2048 }。 |
SecurityOpt |
用于自定义 MLS 系统(如 SELinux)标签的字符串列表。 |
LogConfig |
日志配置,形如 { "Type": "<driver_name>", "Config": {"key1": "val1"}}。可用类型:json-file、syslog、journald、none;syslog 的可选参数为 address。 |
CgroupParent |
容器 cgroup 的父路径。非绝对路径时相对 init 进程的 cgroups 路径;不存在时会自动创建。 |
查询参数:name —— 为容器指定名称,必须匹配 /?[a-zA-Z0-9_-]+。
状态码:201 成功;400 参数错误;404 镜像不存在;406 无法附着(容器未在运行);409 冲突;500 服务端错误。
从源码实现看,当前的 postContainersCreate(daemon/server/router/container/container_routes.go)在处理创建请求时,会先解码请求体,再根据客户端声明的 API 版本做大量"向后兼容"裁剪(例如低版本请求忽略新引入的挂载字段、拒绝低版本客户端使用多网络端点等)——这正是 v1.19 文档中"同一端点在不同版本下行为略有差异"这一设计思路的延续。
2.3 查看容器详情:GET /containers/(id or name)/json
返回容器 id 的底层信息。示例请求:
GET /v1.19/containers/4fa6e0f0c678/json HTTP/1.1
示例响应(节选自原文档完整示例,涵盖 Config、HostConfig、State、NetworkSettings 等关键结构):
HTTP/1.1 200 OK
Content-Type: application/json
{
"AppArmorProfile": "",
"Args": ["-c", "exit 9"],
"Config": {
"AttachStderr": true,
"AttachStdin": false,
"AttachStdout": true,
"Cmd": ["/bin/sh", "-c", "exit 9"],
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
"Hostname": "ba033ac44011",
"Image": "ubuntu",
"Labels": {
"com.example.vendor": "Acme",
"com.example.license": "GPL",
"com.example.version": "1.0"
},
"Tty": false,
"User": ""
},
"Created": "2015-01-06T15:47:31.485331387Z",
"Driver": "overlay2",
"ExecDriver": "native-0.2",
"HostConfig": {
"BlkioWeight": 0,
"CpuShares": 0,
"CpuPeriod": 100000,
"NetworkMode": "bridge",
"OomKillDisable": false,
"Privileged": false,
"ReadonlyRootfs": false,
"PublishAllPorts": false,
"RestartPolicy": {
"MaximumRetryCount": 2,
"Name": "on-failure"
},
"LogConfig": {
"Config": null,
"Type": "json-file"
}
},
"HostnamePath": "/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/hostname",
"HostsPath": "/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/hosts",
"LogPath": "/var/lib/docker/containers/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b-json.log",
"Id": "ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39",
"Image": "04c5d3b7b0656168630d3ba35d8889bd0e9caafcaeb3004d2bfbc47e7c5d35d2",
"MountLabel": "",
"Name": "/boring_euclid",
"NetworkSettings": {
"Bridge": "",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"MacAddress": "",
"PortMapping": null,
"Ports": null
},
"Path": "/bin/sh",
"ProcessLabel": "",
"ResolvConfPath": "/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/resolv.conf",
"RestartCount": 1,
"State": {
"Error": "",
"ExitCode": 9,
"FinishedAt": "2015-01-06T15:47:32.080254511Z",
"OOMKilled": false,
"Paused": false,
"Pid": 0,
"Restarting": false,
"Running": true,
"StartedAt": "2015-01-06T15:47:32.072697474Z"
},
"Volumes": {},
"VolumesRW": {}
}
(原文档响应中 Config 与 HostConfig 还包含全部空值字段,如 Domainname、Entrypoint、ExposedPorts、OpenStdin、StdinOnce、WorkingDir、Binds、CapAdd、CapDrop、ContainerIDFile、CpusetCpus、CpusetMems、Devices、Dns、DnsSearch、ExtraHosts、IpcMode、Links、LxcConf、Memory、MemorySwap、PortBindings、SecurityOpt、VolumesFrom、Ulimits 等,含义同 2.2 节参数表。)
状态码:200 无错误;404 无此容器;500 服务端错误。
2.4 查看容器内进程:GET /containers/(id or name)/top
列出容器内运行的进程。在 Unix 系统上通过执行 ps 命令实现;该端点在 Windows 上不受支持。
示例请求与响应(默认 ps -ef 参数):
GET /v1.19/containers/4fa6e0f0c678/top HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"Titles" : [
"UID", "PID", "PPID", "C", "STIME", "TTY", "TIME", "CMD"
],
"Processes" : [
[
"root", "13642", "882", "0", "17:03", "pts/0", "00:00:00", "/bin/bash"
],
[
"root", "13735", "13642", "0", "17:06", "pts/0", "00:00:00", "sleep 10"
]
]
}
指定 ps_args=aux 时:
GET /v1.19/containers/4fa6e0f0c678/top?ps_args=aux HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"Titles" : [
"USER","PID","%CPU","%MEM","VSZ","RSS","TTY","STAT","START","TIME","COMMAND"
],
"Processes" : [
[
"root","13642","0.0","0.1","18172","3184","pts/0","Ss","17:03","0:00","/bin/bash"
],
[
"root","13895","0.0","0.0","4348","692","pts/0","S+","17:15","0:00","sleep 10"
]
]
}
查询参数:ps_args —— 传给 ps 的参数(如 aux),默认 -ef。
状态码:200 无错误;404 无此容器;500 服务端错误。
2.5 获取容器日志:GET /containers/(id or name)/logs
获取容器 id 的 stdout 与 stderr 日志。
注意:该端点仅对使用
json-file或journald日志驱动的容器有效。
示例请求:
GET /v1.19/containers/4fa6e0f0c678/logs?stderr=1&stdout=1×tamps=1&follow=1&tail=10&since=1428990821 HTTP/1.1
示例响应:
HTTP/1.1 101 UPGRADED
Content-Type: application/vnd.docker.raw-stream
Connection: Upgrade
Upgrade: tcp
{{ STREAM }}
查询参数:
| 参数 | 说明 |
|---|---|
follow |
1/True/true 或 0/False/false,是否返回流式输出。默认 false。 |
stdout |
是否显示 stdout 日志。默认 false。 |
stderr |
是否显示 stderr 日志。默认 false。 |
since |
UNIX 时间戳(整数),只输出该时间戳之后的日志。默认 0(不过滤)。 |
timestamps |
是否为每行日志打印时间戳。默认 false。 |
tail |
输出日志末尾的指定行数:all 或 <number>。默认 all。 |
状态码:101 无错误,提示代理进行连接劫持;200 无错误且未携带 Upgrade 头;404 无此容器;500 服务端错误。
从当前源码可以看到该端点仍然遵循同样的设计:先校验参数(stdout/stderr 至少指定其一),再根据 tty 决定流是原始流还是多路复用流,最后通过 logstream.Write 一次性开启流式响应(见 daemon/server/router/container/container_routes.go 的 getContainersLogs,其中注释明确说明"一旦开始写流就无法再报告容器不存在等错误",所以参数校验必须前置)。
2.6 查看容器文件系统变更:GET /containers/(id or name)/changes
示例请求:
GET /v1.19/containers/4fa6e0f0c678/changes HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"Path": "/dev",
"Kind": 0
},
{
"Path": "/dev/kmsg",
"Kind": 1
},
{
"Path": "/test",
"Kind": 1
}
]
Kind 取值:0 = Modify(修改);1 = Add(新增);2 = Delete(删除)。
状态码:200 无错误;404 无此容器;500 服务端错误。
2.7 导出容器:GET /containers/(id or name)/export
导出容器 id 的内容。示例请求:
GET /v1.19/containers/4fa6e0f0c678/export HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/octet-stream
{{ TAR STREAM }}
状态码:200 无错误;404 无此容器;500 服务端错误。
2.8 获取容器资源统计:GET /containers/(id or name)/stats
该端点返回容器资源使用统计的实时流。示例请求:
GET /v1.19/containers/redis1/stats HTTP/1.1
示例响应(单帧统计,包含网络、内存、块 IO、CPU 四大块):
HTTP/1.1 200 OK
Content-Type: application/json
{
"read" : "2015-01-08T22:57:31.547920715Z",
"network" : {
"rx_dropped" : 0,
"rx_bytes" : 648,
"rx_errors" : 0,
"tx_packets" : 8,
"tx_dropped" : 0,
"rx_packets" : 8,
"tx_errors" : 0,
"tx_bytes" : 648
},
"memory_stats" : {
"stats" : {
"total_pgmajfault" : 0,
"cache" : 0,
"mapped_file" : 0,
"total_inactive_file" : 0,
"pgpgout" : 414,
"rss" : 6537216,
"total_mapped_file" : 0,
"writeback" : 0,
"unevictable" : 0,
"pgpgin" : 477,
"total_unevictable" : 0,
"pgmajfault" : 0,
"total_rss" : 6537216,
"total_rss_huge" : 6291456,
"total_writeback" : 0,
"total_inactive_anon" : 0,
"rss_huge" : 6291456,
"hierarchical_memory_limit" : 67108864,
"total_pgfault" : 964,
"total_active_file" : 0,
"active_anon" : 6537216,
"total_active_anon" : 6537216,
"total_pgpgout" : 414,
"total_cache" : 0,
"inactive_anon" : 0,
"active_file" : 0,
"pgfault" : 964,
"inactive_file" : 0,
"total_pgpgin" : 477
},
"max_usage" : 6651904,
"usage" : 6537216,
"failcnt" : 0,
"limit" : 67108864
},
"blkio_stats" : {},
"cpu_stats" : {
"cpu_usage" : {
"percpu_usage" : [
8646879,
24472255,
36438778,
30657443
],
"usage_in_usermode" : 50000000,
"total_usage" : 100215355,
"usage_in_kernelmode" : 30000000
},
"system_cpu_usage" : 739306590000000,
"throttling_data" : {"periods":0,"throttled_periods":0,"throttled_time":0}
},
"precpu_stats" : {
"cpu_usage" : {
"percpu_usage" : [
8646879,
24350896,
36438778,
30657443
],
"usage_in_usermode" : 50000000,
"total_usage" : 100093996,
"usage_in_kernelmode" : 30000000
},
"system_cpu_usage" : 9492140000000,
"throttling_data" : {"periods":0,"throttled_periods":0,"throttled_time":0}
}
}
其中 precpu_stats 是上一次读取的 CPU 统计,用于计算 CPU 使用率百分比,并非 cpu_stats 的精确副本。
查询参数:stream —— 1/True/true 或 0/False/false,为 false 时只拉取一次统计即断开。默认 true。
状态码:200 无错误;404 无此容器;500 服务端错误。
从源码看,stream 参数的默认值与行为在现代实现中保持一致:stream=true 时通过 WriteFlusher 持续刷写统计帧(见 daemon/server/router/container/container_routes.go 的 getContainersStats)。
2.9 调整容器 TTY:POST /containers/(id or name)/resize?h=<height>&w=<width>
调整容器 id 的 TTY 大小。注意:必须重启容器,resize 才会生效。
示例请求:
POST /v1.19/containers/4fa6e0f0c678/resize?h=40&w=80 HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Length: 0
Content-Type: text/plain; charset=utf-8
查询参数:h —— tty 会话高度;w —— tty 会话宽度。
状态码:200 无错误;404 无此容器;500 无法调整容器。
2.10 生命周期控制:start / stop / restart / kill / pause / unpause
以下端点共享"返回 204 No Content"的成功语义,参数与状态码如下(请求体均为空):
启动容器 POST /containers/(id or name)/start
注意:出于向后兼容,v1.19 的该端点接受 JSON 编码的
HostConfig作为请求体(字段定义见 2.2 节"创建容器")。
POST /v1.19/containers/e90e34656806/start HTTP/1.1
→ HTTP/1.1 204 No Content
状态码:204 无错误;304 容器已在运行;404 无此容器;500 服务端错误。
停止容器 POST /containers/(id or name)/stop
POST /v1.19/containers/e90e34656806/stop?t=5 HTTP/1.1
→ HTTP/1.1 204 No Content
查询参数:t —— 强制杀死容器前等待的秒数。状态码:204 无错误;304 容器已停止;404 无此容器;500 服务端错误。
重启容器 POST /containers/(id or name)/restart
POST /v1.19/containers/e90e34656806/restart?t=5 HTTP/1.1
→ HTTP/1.1 204 No Content
查询参数:t —— 强制杀死前等待的秒数。状态码:204 无错误;404 无此容器;500 服务端错误。
杀死容器 POST /containers/(id or name)/kill
POST /v1.19/containers/e90e34656806/kill HTTP/1.1
→ HTTP/1.1 204 No Content
查询参数:signal —— 要发送的信号,整数或 SIGINT 这类字符串。未指定时假定为 SIGKILL,且调用会等待容器退出。状态码:204 无错误;404 无此容器;500 服务端错误。
暂停 / 恢复 POST /containers/(id or name)/pause 与 POST /containers/(id or name)/unpause
POST /v1.19/containers/e90e34656806/pause HTTP/1.1
→ HTTP/1.1 204 No Content
两者状态码相同:204 无错误;404 无此容器;500 服务端错误。
值得对照的是当前源码中的实现细节:stop/restart 端点解析 t 参数并作为超时传给后端(见 daemon/server/router/container/container_routes.go),而 start 端点在现代实现中已经拒绝非空请求体("starting container with non-empty request body was deprecated since API v1.22 and removed in v1.24",见同文件 postContainersStart)——也就是说 v1.19 文档中"start 接受 HostConfig 请求体"的兼容行为在后续版本中被移除了。
2.11 重命名容器:POST /containers/(id or name)/rename
POST /v1.19/containers/e90e34656806/rename?name=new_name HTTP/1.1
→ HTTP/1.1 204 No Content
查询参数:name —— 容器新名称。状态码:204 无错误;404 无此容器;409 冲突(名称已被占用);500 服务端错误。
2.12 附着容器:POST /containers/(id or name)/attach
POST /v1.19/containers/16253994b7c4/attach?logs=1&stream=0&stdout=1 HTTP/1.1
HTTP/1.1 101 UPGRADED
Content-Type: application/vnd.docker.raw-stream
Connection: Upgrade
Upgrade: tcp
{{ STREAM }}
查询参数(均为 1/True/true 或 0/False/false,默认 false):
| 参数 | 说明 |
|---|---|
logs |
是否返回历史日志。 |
stream |
是否返回流。 |
stdin |
stream=true 时是否附着 stdin。 |
stdout |
logs=true 时返回 stdout 日志;stream=true 时附着 stdout。 |
stderr |
logs=true 时返回 stderr 日志;stream=true 时附着 stderr。 |
状态码:101 无错误,提示代理进行劫持;200 无错误且未携带 Upgrade 头;400 参数错误;404 无此容器;500 服务端错误。
流协议细节(v1.19 客户端必须理解的核心):
- 若创建容器时启用了
Tty,流就是进程 PTY 与客户端stdin的原始数据; - 若未启用 TTY,流会被多路复用,以分离
stdout与stderr。其格式为 Header + Payload 帧:
HEADER:前 8 个字节编码"该帧写入哪个流"以及帧大小(后 4 字节为 uint32,大端序):
header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}
STREAM_TYPE 取值:0 = stdin(会被写到 stdout);1 = stdout;2 = stderr。
PAYLOAD:紧随其后的原始流数据。
最简实现流程:1) 读 8 字节;2) 按首字节判断 stdout 或 stderr;3) 从后 4 字节取帧大小;4) 读出该数量的数据并输出到对应流;5) 回到 1)。
这份文档描述与当前仓库的参考实现逐字对应:api/pkg/stdcopy/stdcopy.go 中定义了 Stdin=0、Stdout=1、Stderr=2(以及后来新增的 Systemerr=3)与 stdWriterPrefixLen = 8、stdWriterFdIndex = 0、stdWriterSizeIndex = 4 等常量;StdCopy 函数正是按"读满 8 字节头部 → 按首字节分流 → 大端解析帧长 → 拷贝负载"的循环实现的。手写 v1.19 客户端解码 attach/logs 流时,可以直接参照该实现。
2.13 附着容器(websocket):GET /containers/(id or name)/attach/ws
通过 websocket 附着容器 id,实现 websocket 协议握手。
GET /v1.19/containers/e90e34656806/attach/ws?logs=0&stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
→ {{ STREAM }}
查询参数:logs —— 是否返回日志,默认 false;stream —— 是否返回流,默认 false。
状态码:200 无错误;400 参数错误;404 无此容器;500 服务端错误。
2.14 等待容器:POST /containers/(id or name)/wait
阻塞直到容器 id 停止,然后返回退出码。
POST /v1.19/containers/16253994b7c4/wait HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{"StatusCode": 0}
状态码:200 无错误;404 无此容器;500 服务端错误。
2.15 删除容器:DELETE /containers/(id or name)
DELETE /v1.19/containers/16253994b7c4?v=1 HTTP/1.1
→ HTTP/1.1 204 No Content
查询参数(均为布尔,默认 false):v —— 同时移除关联的卷;force —— 先 kill 再删除;link —— 移除指定的关联链接。
状态码:204 无错误;400 参数错误;404 无此容器;409 冲突;500 服务端错误。
2.16 从容器复制文件:POST /containers/(id or name)/copy
复制容器 id 中的文件或目录。
POST /v1.19/containers/4fa6e0f0c678/copy HTTP/1.1
Content-Type: application/json
Content-Length: 12345
{
"Resource": "test.txt"
}
HTTP/1.1 200 OK
Content-Type: application/x-tar
{{ TAR STREAM }}
状态码:200 无错误;404 无此容器;500 服务端错误。
3. 镜像端点(2.2 Images)
3.1 列出镜像:GET /images/json
GET /v1.19/images/json?all=0 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"RepoTags": [
"ubuntu:12.04",
"ubuntu:precise",
"ubuntu:latest"
],
"Id": "8dbd9e392a964056420e5d58ca5cc376ef18e2de93b5cc90e868a1bbc8318c1c",
"Created": 1365714795,
"Size": 131506275,
"VirtualSize": 131506275,
"Labels": {}
},
{
"RepoTags": [
"ubuntu:12.10",
"ubuntu:quantal"
],
"ParentId": "27cf784147099545",
"Id": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"Created": 1364102658,
"Size": 24653,
"VirtualSize": 180116135,
"Labels": {
"com.example.version": "v1"
}
}
]
带 digest 信息的请求与响应:
GET /v1.19/images/json?digests=1 HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"Created": 1420064636,
"Id": "4986bf8c15363d1c5d15512d5266f8777bfba4974ac56e3270e7760f6f0a8125",
"ParentId": "ea13149945cb6b1e746bf28032f02e9b5a793523481a0a18645fc77ad53c4ea2",
"RepoDigests": [
"localhost:5000/test/busybox@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf"
],
"RepoTags": [
"localhost:5000/test/busybox:latest",
"playdate:latest"
],
"Size": 0,
"VirtualSize": 2429728,
"Labels": {}
}
]
同一镜像 Id 可关联多个仓库标签(RepoTags),任一 RepoTags 值(如 localhost:5000/test/busybox:latest 或 playdate:latest)都可用来引用该镜像;同样可以用 RepoDigests 值引用(如 localhost:5000/test/busybox@sha256:cbbf2f9a...),此时若某仓库没有对应 digest,则该仓库不会出现在 RepoDigests 数组中。
查询参数:
| 参数 | 说明 |
|---|---|
all |
1/True/true 或 0/False/false,默认 false。 |
filters |
JSON 编码的 map[string][]string 过滤器。可用:dangling=true;label=key 或 label="key=value"。 |
filter |
只返回指定名称的镜像。 |
3.2 从 Dockerfile 构建镜像:POST /build
POST /v1.19/build HTTP/1.1
Content-Type: application/x-tar
{{ TAR STREAM }}
HTTP/1.1 200 OK
Content-Type: application/json
{"stream": "Step 1/5..."}
{"stream": "..."}
{"error": "Error...", "errorDetail": {"code": 123, "message": "Error..."}}
输入流必须是用 identity(不压缩)、gzip、bzip2、xz 之一压缩的 tar 归档。归档中必须包含构建指令文件(通常位于归档根目录、名为 Dockerfile),可用 dockerfile 参数指定其他构建指令文件。归档还可包含任意数量的其他文件,构建时可通过 ADD 指令访问。
守护进程会在构建前对 Dockerfile 做初步校验,语法错误直接返回错误;此后逐条执行指令,直到输出新镜像 ID。客户端断开连接(退出或被 kill)即取消构建。
查询参数:
| 参数 | 说明 |
|---|---|
dockerfile |
构建上下文内 Dockerfile 的路径;指定 remote 且指向单个文件时忽略。 |
t |
name:tag 形式的镜像名与可选标签;省略 tag 时默认 latest。 |
remote |
Git 仓库 URI 或 HTTP/HTTPS URI 构建源;若 URI 指向文件,则文件内容被放入名为 Dockerfile 的文件。 |
q |
抑制冗长的构建输出。 |
nocache |
构建时不使用缓存。 |
pull |
即使本地已有旧镜像也尝试拉取。 |
rm |
构建成功后删除中间容器(默认行为)。 |
forcerm |
总是删除中间容器(含 rm)。 |
memory / memswap |
构建内存限制 / 内存+swap 总量,-1 表示无限制 swap。 |
cpushares / cpusetcpus / cpuperiod / cpuquota |
构建的 CPU 限制,语义同 2.2 节 HostConfig。 |
请求头:Content-type 设为 application/x-tar;X-Registry-Config —— base64 编码的 ConfigFile 对象。
状态码:200 无错误;500 服务端错误。
3.3 创建镜像(拉取或导入):POST /images/create
POST /v1.19/images/create?fromImage=busybox&tag=latest HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{"status": "Pulling..."}
{"status": "Pulling", "progress": "1 B/ 100 B", "progressDetail": {"current": 1, "total": 100}}
{"error": "Invalid..."}
...
从 registry 拉取镜像时,可用 X-Registry-Auth 头携带 base64 编码的 AuthConfig 对象。
查询参数:
| 参数 | 说明 |
|---|---|
fromImage |
要拉取的镜像名。 |
fromSrc |
导入源:可以是拉取镜像的 URL,也可以是 -(从请求体读取)。 |
repo |
仓库名。 |
tag |
标签。拉取时若为空,则拉取该镜像的所有标签。 |
请求头:X-Registry-Auth —— base64 编码的 AuthConfig 对象。
状态码:200 无错误;404 仓库不存在或无读权限;500 服务端错误。
3.4 查看镜像详情:GET /images/(name)/json
GET /v1.19/images/ubuntu/json HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"Created": "2013-03-23T22:24:18.818426-07:00",
"Container": "3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0",
"ContainerConfig": {
"Hostname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": true,
"OpenStdin": true,
"StdinOnce": false,
"Env": null,
"Cmd": ["/bin/bash"],
"Dns": null,
"Image": "ubuntu",
"Labels": {
"com.example.vendor": "Acme",
"com.example.license": "GPL",
"com.example.version": "1.0"
},
"Volumes": null,
"VolumesFrom": "",
"WorkingDir": ""
},
"Id": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"Parent": "27cf784147099545",
"Size": 6824592
}
状态码:200 无错误;404 无此镜像;500 服务端错误。
3.5 查看镜像历史:GET /images/(name)/history
GET /v1.19/images/ubuntu/history HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"Id": "3db9c44f45209632d6050b35958829c3a2aa256d81b9a7be45b362ff85c54710",
"Created": 1398108230,
"CreatedBy": "/bin/sh -c #(nop) ADD file:eb15dbd63394e063b805a3c32ca7bf0266ef64676d5a6fab4801f2e81e2a5148 in /",
"Tags": ["ubuntu:lucid", "ubuntu:10.04"],
"Size": 182964289,
"Comment": ""
},
{
"Id": "6cfa4d1f33fb861d4d114f43b25abd0ac737509268065cdfd69d544a59c85ab8",
"Created": 1398108222,
"CreatedBy": "/bin/sh -c #(nop) MAINTAINER Tianon Gravi <admwiggin@gmail.com> - mkimage-debootstrap.sh -i iproute,iputils-ping,ubuntu-minimal -t lucid.tar.xz lucid http://archive.ubuntu.com/ubuntu/",
"Tags": null,
"Size": 0,
"Comment": ""
},
{
"Id": "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158",
"Created": 1371157430,
"CreatedBy": "",
"Tags": ["scratch12:latest", "scratch:latest"],
"Size": 0,
"Comment": "Imported from -"
}
]
状态码:200 无错误;404 无此镜像;500 服务端错误。
3.6 推送镜像:POST /images/(name)/push
POST /v1.19/images/test/push HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{"status": "Pushing..."}
{"status": "Pushing", "progress": "1/? (n/a)", "progressDetail": {"current": 1}}
{"error": "Invalid..."}
...
若推送到私有 registry,镜像必须已经打了引用该 registry hostname:port 仓库的 tag,且 URL 中应使用该仓库名(与命令行流程一致):
POST /v1.19/images/registry.acme.com:5000/test/push HTTP/1.1
查询参数:tag —— 镜像在 registry 上关联的标签(可选)。
请求头:X-Registry-Auth —— base64 编码的 AuthConfig 对象。
状态码:200 无错误;404 无此镜像;500 服务端错误。
3.7 为镜像打标签:POST /images/(name)/tag
POST /v1.19/images/test/tag?repo=myrepo&force=0&tag=v42 HTTP/1.1
→ HTTP/1.1 201 Created
查询参数:repo —— 目标仓库;force —— 布尔,默认 false;tag —— 新标签名。
状态码:201 无错误;400 参数错误;404 无此镜像;409 冲突;500 服务端错误。
3.8 删除镜像:DELETE /images/(name)
DELETE /v1.19/images/test HTTP/1.1
HTTP/1.1 200 OK
Content-type: application/json
[
{"Untagged": "3e2f21a89f"},
{"Deleted": "3e2f21a89f"},
{"Deleted": "53b4f83ac9"}
]
查询参数:force —— 布尔,默认 false;noprune —— 布尔,默认 false。
状态码:200 无错误;404 无此镜像;409 冲突;500 服务端错误。
3.9 搜索镜像:GET /images/search
在 Docker Hub 上搜索镜像,返回 is_trusted 与 is_automated 镜像(当时两者被视为等同;文档预告未来 is_trusted 将被 is_automated 取代)。注意:响应键名自 API v1.6 起发生变化,以反映 registry 服务器发送给守护进程请求的 JSON。
GET /v1.19/images/search?term=sshd HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"star_count": 12,
"is_official": false,
"name": "wma55/u1210sshd",
"is_trusted": false,
"is_automated": false,
"description": ""
},
{
"star_count": 10,
"is_official": false,
"name": "jdswinbank/sshd",
"is_trusted": false,
"is_automated": false,
"description": ""
},
{
"star_count": 18,
"is_official": false,
"name": "vgauthier/sshd",
"is_trusted": false,
"is_automated": false,
"description": ""
}
]
查询参数:term —— 搜索词。状态码:200 无错误;500 服务端错误。
3.10 导出 / 加载镜像 tarball
获取单个仓库的所有镜像 tarball GET /images/(name)/get
获取 name 指定仓库的全部镜像与元数据。若 name 是具体的 name+tag(如 ubuntu:latest)或镜像 ID,则只返回该镜像及其父镜像;镜像 ID 情形下 tarball 中不含 repositories 文件(因为没有任何镜像名引用)。
GET /v1.19/images/ubuntu/get
→ HTTP/1.1 200 OK
Content-Type: application/x-tar
Binary data stream
批量获取 GET /images/get:对 names 参数的每个值应用同样的"单标签/ID 只返回自身及父镜像"规则。
GET /v1.19/images/get?names=myname%2Fmyapp%3Alatest&names=busybox
→ HTTP/1.1 200 OK
Content-Type: application/x-tar
Binary data stream
加载 POST /images/load:把一组镜像与标签加载进仓库。
POST /v1.19/images/load
Content-Type: application/x-tar
Content-Length: 12345
(tarball 位于请求体)
→ HTTP/1.1 200 OK
三个端点状态码均为:200 无错误;500 服务端错误。
3.11 镜像 tarball 格式
镜像 tarball 中每个镜像层一个目录(以长 ID 命名),每个目录包含:
VERSION:文件格式版本,当前为1.0;json:层详细信息,类似docker inspect layer_id的输出;layer.tar:包含该层文件系统变更的 tar 文件。
layer.tar 中包含 aufs 风格的 .wh..wh.aufs 文件与目录,用于保存属性变更与删除记录。
若 tarball 定义了仓库,则根目录还应包含一个 repositories 文件,列出仓库/标签名到层 ID 的映射:
{"hello-world":
{"latest": "565a9d68a73f6706862bfe8409a7f659776d4d60a8d096eb4a3cbce6999cc2a1"}
}
4. 杂项与 Exec 端点(2.3 Misc)
4.1 校验认证配置:POST /auth
获取默认用户名与邮箱。
POST /v1.19/auth HTTP/1.1
Content-Type: application/json
Content-Length: 12345
{
"username": "hannibal",
"password": "xxxx",
"email": "hannibal@a-team.com",
"serveraddress": "https://index.docker.io/v1/"
}
→ HTTP/1.1 200 OK
状态码:200 或 204 无错误;500 服务端错误。
4.2 系统信息:GET /info
GET /v1.19/info HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"Containers": 11,
"CpuCfsPeriod": true,
"CpuCfsQuota": true,
"Debug": false,
"DockerRootDir": "/var/lib/docker",
"Driver": "btrfs",
"DriverStatus": [[""]],
"ExecutionDriver": "native-0.1",
"ExperimentalBuild": false,
"HttpProxy": "http://test:test@localhost:8080",
"HttpsProxy": "https://test:test@localhost:8080",
"ID": "7TRN:IPZB:QYBB:VPBQ:UMPP:KARE:6ZNR:XE6T:7EWV:PKF4:ZOJD:TPYS",
"IPv4Forwarding": true,
"Images": 16,
"IndexServerAddress": "https://index.docker.io/v1/",
"InitPath": "/usr/bin/docker",
"InitSha1": "",
"KernelVersion": "3.12.0-1-amd64",
"Labels": ["storage=ssd"],
"MemTotal": 2099236864,
"MemoryLimit": true,
"NCPU": 1,
"NEventsListener": 0,
"NFd": 11,
"NGoroutines": 21,
"Name": "prod-server-42",
"NoProxy": "9.81.1.160",
"OomKillDisable": true,
"OperatingSystem": "Boot2Docker",
"RegistryConfig": {
"IndexConfigs": {
"docker.io": {
"Mirrors": null,
"Name": "docker.io",
"Official": true,
"Secure": true
}
},
"InsecureRegistryCIDRs": ["127.0.0.0/8"]
},
"SwapLimit": false,
"SystemTime": "2015-03-10T11:11:23.730591467-07:00"
}
状态码:200 无错误;500 服务端错误。
4.3 版本信息:GET /version
GET /v1.19/version HTTP/1.1
HTTP/1.1 200 OK
Content-Type: application/json
{
"Version": "1.5.0",
"Os": "linux",
"KernelVersion": "3.18.5-tinycore64",
"GoVersion": "go1.4.1",
"GitCommit": "a8a31ef",
"Arch": "amd64",
"ApiVersion": "1.19"
}
状态码:200 无错误;500 服务端错误。
4.4 心跳检测:GET /_ping
GET /v1.19/_ping HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/plain
OK
状态码:200 无错误;500 服务端错误。
4.5 由容器变更创建镜像:POST /commit
POST /v1.19/commit?container=44c004db4b17&comment=message&repo=myrepo HTTP/1.1
Content-Type: application/json
Content-Length: 12345
{
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"PortSpecs": null,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": null,
"Cmd": ["date"],
"Volumes": {"/tmp": {}},
"Labels": {
"key1": "value1",
"key2": "value2"
},
"WorkingDir": "",
"NetworkDisabled": false,
"ExposedPorts": {"22/tcp": {}}
}
HTTP/1.1 201 Created
Content-Type: application/json
{"Id": "596069db4bf5"}
JSON 参数:config —— 容器的配置(即请求体中的 container.Config 字段)。
查询参数:container —— 源容器;repo —— 仓库;tag —— 标签;comment —— 提交说明;author —— 作者(如 "John Hannibal Smith <hannibal@a-team.com>")。
状态码:201 无错误;404 无此容器;500 服务端错误。
对应地,当前源码的 postCommit 会先解析表单与请求体中的可选 container.Config(请求体可为空),再把 repo/tag 组合为引用并委托后端 CreateImageFromContainer(见 daemon/server/router/container/container_routes.go)。
4.6 监控事件流:GET /events
以流式方式实时获取 Docker 事件。容器事件:attach, commit, copy, create, destroy, die, exec_create, exec_start, export, kill, oom, pause, rename, resize, restart, start, stop, top, unpause;镜像事件:untag, delete。
GET /v1.19/events?since=1374067924
HTTP/1.1 200 OK
Content-Type: application/json
{"status": "create", "id": "dfdf82bd3881","from": "ubuntu:latest", "time":1374067924}
{"status": "start", "id": "dfdf82bd3881","from": "ubuntu:latest", "time":1374067924}
{"status": "stop", "id": "dfdf82bd3881","from": "ubuntu:latest", "time":1374067966}
{"status": "destroy", "id": "dfdf82bd3881","from": "ubuntu:latest", "time":1374067970}
查询参数:
| 参数 | 说明 |
|---|---|
since |
时间戳。输出该时间戳之后创建的所有事件,然后继续流式输出。 |
until |
时间戳。输出到该时间戳的事件并停止流。 |
filters |
JSON 编码的 map[string][]string 过滤器。可用:container=<string>;event=<string>;image=<string>。 |
状态码:200 无错误;500 服务端错误。
4.7 Exec:在运行容器中执行命令
Exec 流程分四步:创建实例 → 启动 → (可选)调整 TTY → 检查状态。
Exec Create POST /containers/(id or name)/exec:在运行中的容器 id 内设置一个 exec 实例。
POST /v1.19/containers/e90e34656806/exec HTTP/1.1
Content-Type: application/json
Content-Length: 12345
{
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"Cmd": ["sh"],
"Tty": true,
"User": "123:456"
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"Id": "f90e34656806",
"Warnings":[]
}
JSON 参数:AttachStdin/AttachStdout/AttachStderr —— 是否附着到 exec 命令的对应流;Tty —— 是否分配伪 TTY;Cmd —— 要运行的命令(字符串或字符串数组);User —— 运行用户,格式为 "user"、"user:group"、"uid" 或 "uid:gid"。
状态码:201 无错误;404 无此容器。
Exec Start POST /exec/(id)/start:启动先前创建的 exec 实例。detach 为 true 时 API 在启动命令后即返回;否则建立与 exec 命令的交互式会话。
POST /v1.19/exec/e90e34656806/start HTTP/1.1
Content-Type: application/json
Content-Length: 12345
{
"Detach": false,
"Tty": false
}
HTTP/1.1 200 OK
Content-Type: application/vnd.docker.raw-stream
{{ STREAM }}
JSON 参数:Detach —— 与 exec 命令分离;Tty —— 是否分配伪 TTY。状态码:200 无错误;404 无此 exec 实例。流协议与 POST /containers/(id or name)/attach 相同(即 2.12 节的帧格式)。
Exec Resize POST /exec/(id)/resize?h=40&w=80:调整 exec 命令使用的 tty 会话,单位为字符数。仅当创建/启动 exec 时指定了 tty 才有效。
POST /v1.19/exec/e90e34656806/resize?h=40&w=80 HTTP/1.1
Content-Type: text/plain
→ HTTP/1.1 201 Created
Content-Type: text/plain
查询参数:h —— 高度;w —— 宽度。状态码:201 无错误;404 无此 exec 实例。
Exec Inspect GET /exec/(id)/json:返回 exec 命令 id 的底层信息,包括 ID、Running、ExitCode、ProcessConfig(privileged、`
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00