Moby Remote API v1.3:Docker 容器生态 REST API 的完整端点手册与连接劫持机制解析
本文基于 Moby 仓库 api/docs 目录下的历史 API 规范文档,完整梳理 Docker Remote API v1.3 的全部端点定义:容器与镜像的生命周期操作、系统级端点,以及 docker run 背后的 API 调用序列。读完本文,你可以准确掌握 v1.3 每个端点的请求/响应格式、查询参数与状态码语义,并能结合当前 Moby 源码理解 attach 连接劫持(hijacking)协议在客户端与服务端的真实实现。
1. 概述:v1.3 的定位与设计哲学
v1.3 规范开篇给出了三条核心设计原则,这些原则至今仍构成 Moby API 的基石:
- Remote API 正在取代 rcli。早期的 rcli(remote CLI)方案让远程客户端直接执行本地命令,而 Remote API 将其替换为基于 HTTP 的 REST 风格接口,使 CLI、SDK、第三方工具可以统一通过同一协议与 daemon 交互;
- daemon 的默认监听端口为 2375。当前仓库的客户端测试中仍可见
tcp://localhost:2375这样的默认主机地址用法(见 client/client_test.go); - API 总体趋向 REST,但对 attach、pull 等复杂命令会“劫持”(hijack)HTTP 连接,以便在同一个 socket 上双向传输 stdin、stdout 和 stderr。
这一条是 v1.3 最值得深入理解的设计。REST 是请求-响应模型,无法承载长生命周期的双向字节流;attach 需要把用户终端与容器标准 I/O 直接打通,pull 需要把逐层的进度输出流式推回客户端。为此,daemon 在特定端点上放弃 HTTP 语义,直接接管底层 TCP 连接。当前仓库中,客户端侧的实现位于 client/hijack.go:setupHijackConn 函数(见 client/hijack.go#L45-L96)会向请求写入 Connection: Upgrade 与 Upgrade: <proto> 头,收到 101 SwitchingProtocols 后返回裸连接;服务端侧的对应实现见 daemon/attach.go 中的 ContainerAttach(见 daemon/attach.go#L23-L96)。
2. 容器(Containers)端点
2.1 列出容器 GET /containers/json
示例请求:
GET /containers/json?all=1&before=8dfafdbc3a40&size=1 HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"Id": "8dfafdbc3a40",
"Image": "ubuntu:latest",
"Command": "echo 1",
"Created": 1367854155,
"Status": "Exit 0",
"Ports":"",
"SizeRw":12288,
"SizeRootFs":0
},
{
"Id": "9cd87474be90",
"Image": "ubuntu:latest",
"Command": "echo 222222",
"Created": 1367854155,
"Status": "Exit 0",
"Ports":"",
"SizeRw":12288,
"SizeRootFs":0
}
]
查询参数:
| 参数 | 说明 |
|---|---|
all |
1/True/true 或 0/False/false。显示所有容器;默认只显示运行中的容器(默认 false) |
limit |
只显示最近创建的 limit 个容器,包含非运行态 |
since |
只显示创建于该容器 Id 之后的容器,包含非运行态 |
before |
只显示创建于该容器 Id 之前的容器,包含非运行态 |
size |
1/True/true 或 0/False/false。附带显示容器尺寸 |
状态码:200 无错误;400 参数错误;500 服务器错误。
在现行 Moby 服务端,该路由的注册点可直接在 daemon/server/router/container/container.go 中确认(router.NewGetRoute("/containers/json", c.getContainersJSON),见 daemon/server/router/container/container.go#L31),说明 v1.3 文档中的端点形态一直延续到了现代代码。
2.2 创建容器 POST /containers/create
示例请求:
POST /containers/create HTTP/1.1
Content-Type: application/json
{
"Hostname":"",
"User":"",
"Memory":0,
"MemorySwap":0,
"AttachStdin":false,
"AttachStdout":true,
"AttachStderr":true,
"PortSpecs":null,
"Tty":false,
"OpenStdin":false,
"StdinOnce":false,
"Env":null,
"Cmd":[
"date"
],
"Dns":null,
"Image":"ubuntu",
"Volumes":{},
"VolumesFrom":""
}
示例响应:
HTTP/1.1 201 Created
Content-Type: application/json
{
"Id":"e90e34656806"
"Warnings":[]
}
JSON 参数:
config—— 容器配置(上例中各字段即 config 展开后的完整形态:资源限制Memory/MemorySwap、标准流挂载标志AttachStdin/AttachStdout/AttachStderr、伪终端与 stdin 策略Tty/OpenStdin/StdinOnce、入口命令Cmd、基础镜像Image、数据卷声明Volumes/VolumesFrom等)。
状态码:201 无错误;404 容器不存在(例如引用的镜像缺失);406 无法 attach(容器未运行);500 服务器错误。
2.3 查看容器详情 GET /containers/(id)/json
返回容器 id 的底层信息。
示例请求:
GET /containers/4fa6e0f0c678/json HTTP/1.1
示例响应(节选关键结构):
HTTP/1.1 200 OK
Content-Type: application/json
{
"Id": "4fa6e0f0c6786287e131c3852c58a2e01cc697a68231826813597e4994f1d6e2",
"Created": "2013-05-07T14:51:42.041847+02:00",
"Path": "date",
"Args": [],
"Config": {
"Hostname": "4fa6e0f0c678",
"User": "",
"Memory": 0,
"MemorySwap": 0,
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"PortSpecs": null,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": null,
"Cmd": ["date"],
"Dns": null,
"Image": "ubuntu",
"Volumes": {},
"VolumesFrom": ""
},
"State": {
"Running": false,
"Pid": 0,
"ExitCode": 0,
"StartedAt": "2013-05-07T14:51:42.087658+02:01360",
"Ghost": false
},
"Image": "b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"NetworkSettings": {
"IpAddress": "",
"IpPrefixLen": 0,
"Gateway": "",
"Bridge": "",
"PortMapping": null
},
"SysInitPath": "/home/kitty/go/src/github.com/docker/docker/bin/docker",
"ResolvConfPath": "/etc/resolv.conf",
"Volumes": {}
}
响应中 Config 与 POST /containers/create 请求体一一对应,State 描述运行态(含 Pid、ExitCode),NetworkSettings 给出该时代的桥接网络信息(单一 IpAddress/Gateway/Bridge)。
状态码:200 无错误;404 容器不存在;500 服务器错误。
2.4 列出容器内进程 GET /containers/(id)/top
示例请求:
GET /containers/4fa6e0f0c678/top HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"PID":"11935",
"Tty":"pts/2",
"Time":"00:00:00",
"Cmd":"sh"
},
{
"PID":"12140",
"Tty":"pts/2",
"Time":"00:00:00",
"Cmd":"sleep"
}
]
状态码:200 无错误;404 容器不存在;500 服务器错误。
2.5 查看容器文件系统变更 GET /containers/(id)/changes
示例请求:
GET /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/1 等分别对应不同的文件系统变更类别),该端点即现代 docker diff 命令的底层接口。
状态码:200 无错误;404 容器不存在;500 服务器错误。
2.6 导出容器 GET /containers/(id)/export
导出容器 id 的内容,返回 tar 流。
示例请求:
GET /containers/4fa6e0f0c678/export HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/octet-stream
{{ TAR STREAM }}
状态码:200 无错误;404 容器不存在;500 服务器错误。
2.7 启动容器 POST /containers/(id)/start
示例请求:
POST /containers/(id)/start HTTP/1.1
Content-Type: application/json
{
"Binds":["/tmp:/tmp"]
}
示例响应:
HTTP/1.1 204 No Content
Content-Type: text/plain
JSON 参数:
hostConfig—— 容器的宿主配置(可选)。
状态码:200 无错误;404 容器不存在;500 服务器错误。
2.8 停止容器 POST /containers/(id)/stop
示例请求:
POST /containers/e90e34656806/stop?t=5 HTTP/1.1
示例响应:HTTP/1.1 204 OK
查询参数:
t—— 发出 kill 之前等待的秒数(即优雅停止超时)。
状态码:204 无错误;404 容器不存在;500 服务器错误。
2.9 重启容器 POST /containers/(id)/restart
示例请求:
POST /containers/e90e34656806/restart?t=5 HTTP/1.1
示例响应:HTTP/1.1 204 No Content
查询参数:t —— 发出 kill 之前等待的秒数。
状态码:204 无错误;404 容器不存在;500 服务器错误。
2.10 强杀容器 POST /containers/(id)/kill
示例请求:
POST /containers/e90e34656806/kill HTTP/1.1
示例响应:HTTP/1.1 204 No Content
状态码:204 无错误;404 容器不存在;500 服务器错误。
2.11 连接到容器 POST /containers/(id)/attach
attach 是 v1.3 中“连接劫持”机制的典型端点:响应不再遵循 HTTP 语义,而是一个原始流。
示例请求:
POST /containers/16253994b7c4/attach?logs=1&stream=0&stdout=1 HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/vnd.docker.raw-stream
{{ STREAM }}
查询参数(布尔值均接受 1/True/true 或 0/False/false):
| 参数 | 默认值 | 说明 |
|---|---|---|
logs |
false | 回放历史日志 |
stream |
false | 附加实时流 |
stdin |
false | 当 stream=true 时附加到 stdin |
stdout |
false | 当 logs=true 时回放 stdout 日志;当 stream=true 时附加到 stdout |
stderr |
false | 当 logs=true 时回放 stderr 日志;当 stream=true 时附加到 stderr |
状态码:200 无错误;400 参数错误;404 容器不存在;500 服务器错误。
结合当前源码可以验证 v1.3 的设计如何被继承:
- 客户端:
postHijacked与setupHijackConn(client/hijack.go#L16-L96)发起Connection: Upgrade握手,等待101 SwitchingProtocols;为保证长时静默的连接不被网络中间层误判超时,TCP 连接会显式开启 KeepAlive(30 秒周期,见 client/hijack.go#L60-L68),注释中明确提到了防止长命令无输出时触发ECONNRESET的问题。 - 服务端:daemon/attach.go 中
ContainerAttach校验暂停/重启中的容器后,构造stream.AttachConfig(是否使用 stdin/stdout/stderr、是否 TTY、detach 键序列),当multiplexed := !ctr.Config.Tty && req.MuxStreams为真时,用stdcopy的StdWriter把 stdout/stderr 封装成带流标识头的多路复用流再写入同一连接——这正是 v1.3 时代“一个 socket 承载 stdin/stdout/stderr”的完整实现;enableLogs分支则通过日志驱动ReadLogs回放历史日志。
2.12 通过 WebSocket 连接到容器 GET /containers/(id)/attach/ws
v1.3 同时提供了 WebSocket 变体,按 RFC 6455 完成握手,使浏览器等无法做裸 TCP 劫持的客户端也能 attach。
示例请求:
GET /containers/e90e34656806/attach/ws?logs=0&stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
示例响应:{{ STREAM }}(WebSocket 帧流)
查询参数与 2.11 节完全一致(logs、stream、stdin、stdout、stderr,默认均 false)。
状态码:200 无错误;400 参数错误;404 容器不存在;500 服务器错误。
2.13 等待容器退出 POST /containers/(id)/wait
阻塞直到容器 id 停止,然后返回退出码。
示例请求:
POST /containers/16253994b7c4/wait HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
{"StatusCode": 0}
状态码:200 无错误;404 容器不存在;500 服务器错误。
2.14 删除容器 DELETE /containers/(id)
将容器 id 从文件系统中移除。
示例请求:
DELETE /containers/16253994b7c4?v=1 HTTP/1.1
示例响应:HTTP/1.1 204 No Content
查询参数:
v—— 1/True/true 或 0/False/false。同时移除容器关联的卷。默认 false。
状态码:204 无错误;400 参数错误;404 容器不存在;500 服务器错误。
3. 镜像(Images)端点
3.1 列出镜像 GET /images/(format)
format 可为 json(默认)或 viz。
示例请求(json):
GET /images/json?all=0 HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"Repository":"ubuntu",
"Tag":"precise",
"Id":"b750fe79269d",
"Created":1364102658,
"Size":24653,
"VirtualSize":180116135
},
{
"Repository":"ubuntu",
"Tag":"12.04",
"Id":"b750fe79269d",
"Created":1364102658,
"Size":24653,
"VirtualSize":180116135
}
]
注意同一 Id 可同时挂在多个 Repository:Tag 名下,这正是镜像多标签模型的体现。
示例请求(viz):
GET /images/viz HTTP/1.1
示例响应(Graphviz digraph,用于可视化镜像父链):
HTTP/1.1 200 OK
Content-Type: text/plain
digraph docker {
"b750fe79269d" -> "1496068ca813"
base -> "27cf78414709" [style=invis]
"b750fe79269d" [label="b750fe79269d\nubuntu",shape=box,fillcolor="paleturquoise",style="filled,rounded"];
base [style=invisible]
}
查询参数:
all—— 1/True/true 或 0/False/false,显示全部镜像(否则只显示“悬挂于顶层”的镜像)。
状态码:200 无错误;400 参数错误;500 服务器错误。
3.2 创建镜像 POST /images/create
通过从仓库拉取或从源导入来创建镜像。
示例请求:
POST /images/create?fromImage=ubuntu HTTP/1.1
示例响应(逐行 JSON 流):
HTTP/1.1 200 OK
Content-Type: application/json
{"status":"Pulling..."}
{"status":"Pulling", "progress":"1/? (n/a)"}
{"error":"Invalid..."}
...
查询参数:
| 参数 | 说明 |
|---|---|
fromImage |
要拉取的镜像名 |
fromSrc |
要导入的源;- 表示 stdin |
repo |
仓库名 |
tag |
标签 |
registry |
拉取所用的仓库服务器 |
状态码:200 无错误;500 服务器错误。
3.3 向镜像插入文件 POST /images/(name)/insert
把 url 处的文件插入镜像 name 的 path 位置。
示例请求:
POST /images/test/insert?path=/usr&url=myurl HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
{"status":"Inserting..."}
{"status":"Inserting", "progress":"1/? (n/a)"}
{"error":"Invalid..."}
...
查询参数:
url—— 文件来源 URL;path—— 文件在镜像中的存储路径。
状态码:200 无错误;500 服务器错误。
3.4 查看镜像详情 GET /images/(name)/json
示例请求:
GET /images/centos/json HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id":"b750fe79269d2ec9a3c593ef05b4332b1d1a02a62b4accb2c21d589ff2f5f2dc",
"parent":"27cf784147099545",
"created":"2013-03-23T22:24:18.818426-07:00",
"container":"3d67245a8d72ecf13f33dffac9f79dcdf70f75acb84d308770391510e0c23ad0",
"container_config":
{
"Hostname":"",
"User":"",
"Memory":0,
"MemorySwap":0,
"AttachStdin":false,
"AttachStdout":false,
"AttachStderr":false,
"PortSpecs":null,
"Tty":true,
"OpenStdin":true,
"StdinOnce":false,
"Env":null,
"Cmd": ["/bin/bash"],
"Dns":null,
"Image":"centos",
"Volumes":null,
"VolumesFrom":""
},
"Size": 6824592
}
parent 字段暴露了镜像层链(layer chain)关系,是理解早期联合文件系统镜像模型的关键字段。
状态码:200 无错误;404 镜像不存在;500 服务器错误。
3.5 查看镜像历史 GET /images/(name)/history
示例请求:
GET /images/fedora/history HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"Id": "b750fe79269d",
"Created": 1364102658,
"CreatedBy": "/bin/bash"
},
{
"Id": "27cf78414709",
"Created": 1364068391,
"CreatedBy": ""
}
]
状态码:200 无错误;404 镜像不存在;500 服务器错误。
3.6 推送镜像 POST /images/(name)/push
示例请求:
POST /images/test/push HTTP/1.1
{{ authConfig }}
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
{"status":"Pushing..."}
{"status":"Pushing", "progress":"1/? (n/a)"}
{"error":"Invalid..."}
...
状态码:200 无错误;404 镜像不存在;500 服务器错误。
3.7 为镜像打标签 POST /images/(name)/tag
示例请求:
POST /images/test/tag?repo=myrepo&force=0&tag=v42 HTTP/1.1
示例响应:HTTP/1.1 201 OK
查询参数:
repo—— 要打标签的目标仓库;force—— 1/True/true 或 0/False/false,默认 false;tag—— 新标签名。
状态码:201 无错误;400 参数错误;404 镜像不存在;409 冲突(如 force=0 时标签已存在);500 服务器错误。
3.8 删除镜像 DELETE /images/(name)
示例请求:
DELETE /images/test HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-type: application/json
[
{"Untagged": "3e2f21a89f"},
{"Deleted": "3e2f21a89f"},
{"Deleted": "53b4f83ac9"}
]
响应逐条报告每个解标签/删除的层,层被删除的前提是它不再被其他镜像引用。
状态码:200 无错误;404 镜像不存在;409 冲突(如镜像被容器使用);500 服务器错误。
3.9 搜索镜像 GET /images/search
在 Docker Hub 上按关键词搜索镜像。
示例请求:
GET /images/search?term=sshd HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
[
{ "Name":"cespare/sshd", "Description":"" },
{ "Name":"johnfuller/sshd", "Description":"" },
{ "Name":"dhrp/mongodb-sshd", "Description":"" }
]
查询参数:term —— 搜索关键词。
状态码:200 无错误;500 服务器错误。
4. 构建与系统(Misc)端点
4.1 从 stdin 构建镜像 POST /build
示例请求:
POST /build HTTP/1.1
{{ TAR STREAM }}
示例响应:
HTTP/1.1 200 OK
{{ STREAM }}
请求体约定(原文完整保留):
- 流必须是一个 tar 归档,允许 identity(无压缩)、gzip、bzip2、xz 四种压缩算法之一;
- 归档根部必须包含名为
Dockerfile的文件; - 可以包含任意数量的其他文件,它们将出现在构建上下文中(供
ADD等指令使用); Content-Type请求头应设置为application/tar。
查询参数:
| 参数 | 说明 |
|---|---|
t |
构建成功后应用到新镜像的仓库名(可带标签) |
remote |
构建源 URI(git 或 HTTPS/HTTP) |
q |
抑制冗长的构建输出 |
状态码:200 无错误;500 服务器错误。
4.2 校验仓库认证配置 POST /auth
示例请求:
POST /auth HTTP/1.1
Content-Type: application/json
{
"username":"hannibal",
"password":"xxxx",
"email":"hannibal@a-team.com"
}
示例响应:HTTP/1.1 200 OK(Content-Type: text/plain,无正文)
状态码:200 无错误;204 无错误;500 服务器错误。
4.3 查看系统信息 GET /info
示例请求:
GET /info HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
{
"Containers":11,
"Images":16,
"Debug":false,
"NFd": 11,
"NGoroutines":21,
"MemoryLimit":true,
"SwapLimit":false,
"EventsListeners":"0",
"LXCVersion":"0.7.5",
"KernelVersion":"3.8.0-19-generic"
}
字段涵盖容器/镜像计数、daemon 调试状态、文件描述符与 goroutine 数量、cgroup 能力探测(MemoryLimit/SwapLimit)、事件监听器数量,以及 v1.3 时代的运行时(LXC)与内核版本。
状态码:200 无错误;500 服务器错误。
4.4 查看版本信息 GET /version
示例请求:
GET /version HTTP/1.1
示例响应:
HTTP/1.1 200 OK
Content-Type: application/json
{
"Version":"0.2.2",
"GitCommit":"5a2a5cc+CHANGES",
"GoVersion":"go1.0.3"
}
状态码:200 无错误;500 服务器错误。
4.5 从容器变更创建镜像 POST /commit
示例请求:
POST /commit?container=44c004db4b17&m=message&repo=myrepo HTTP/1.1
Content-Type: application/json
{
"Cmd": ["cat", "/world"],
"PortSpecs":["22"]
}
示例响应:
HTTP/1.1 201 OK
Content-Type: application/vnd.docker.raw-stream
{"Id": "596069db4bf5"}
查询参数:
container—— 源容器;repo—— 目标仓库;tag—— 标签;m—— commit 说明信息;author—— 作者(如"John Hannibal Smith <hannibal@a-team.com>")。
状态码:201 无错误;404 容器不存在;500 服务器错误。
4.6 监听事件 GET /events
以流式(实时)或轮询(since)方式获取事件。容器会上报:
create, destroy, die, export, kill, pause, restart, start, stop, unpause
镜像会上报:
untag, delete
示例请求:
GET /events?since=1374067924
示例响应(逐行 JSON 流):
HTTP/1.1 200 OK
Content-Type: application/json
{"status":"create","id":"dfdf82bd3881","time":1374067924}
{"status":"start","id":"dfdf82bd3881","time":1374067924}
{"status":"stop","id":"dfdf82bd3881","time":1374067966}
{"status":"destroy","id":"dfdf82bd3881","time":1374067970}
查询参数:since —— 用于轮询的时间戳。
状态码:200 无错误;500 服务器错误。
5. 深入机制:docker run 的 API 分解、Hijacking 与 CORS
5.1 docker run 内部发生了什么
v1.3 文档明确给出了 docker run 由上述端点拼装而成的调用序列:
- 创建容器(
POST /containers/create); - 若返回
404,说明镜像不存在:- 先执行拉取(
POST /images/create); - 然后重试创建容器;
- 先执行拉取(
- 启动容器(
POST /containers/(id)/start); - 若未使用 detached 模式:
- 使用
logs=1(拿到容器启动以来的 stdout/stderr)与stream=1附加到容器(POST /containers/(id)/attach);
- 使用
- 若是 detached 模式或仅附加了 stdin:
- 打印容器 Id。
这段说明把“一条命令”还原为“一组可审计的 HTTP 调用”,是理解 docker CLI 一切行为如何映射到 API 的最佳范本。
5.2 Hijacking(连接劫持)
文档原文指出:在本版本中,/attach 使用 hijacking 在同一个 socket 上承载 stdin、stdout 和 stderr,未来可能变更。
当前仓库中的证据表明该机制不但保留,而且高度工程化:
- 客户端
setupHijackConn(client/hijack.go#L45-L96)先以Connection: Upgrade+Upgrade头发起请求,服务端以101 SwitchingProtocols应答后,连接即脱离 HTTP 层直接收发原始字节;若应答码非 101,客户端会立即报错unable to upgrade to %s。 - 针对“长时间静默输出”的长命令,客户端在 TCP 层设置 30 秒 KeepAlive,防止中间网络因空闲触发连接超时(client/hijack.go#L60-L68)。
- 服务端 attach 路径(daemon/attach.go)区分 TTY 与多路复用两种模式:非 TTY 时用
stdcopy编码(stdout/stderr 各加流类型头)把两路输出复用到同一条流上,客户端再解码分流;TTY 模式则直通原始字节保持终端语义。客户端HijackedResponse.MediaType()方法(client/hijack.go#L150-L158)正是依据响应头中的Content-Type来告知上层“拿到的是原始流还是多路复用流”。
5.3 跨域(CORS)请求
v1.3 时代启用跨域访问 Remote API 的方式是在 daemon 模式下追加 --api-enable-cors 标志:
docker -d -H="192.168.1.9:2375" --api-enable-cors
需要说明的是:该开关允许浏览器端(如管理控制台)跨源调用 API。由于 v1.3 的默认 2375 端口为明文 HTTP,跨域与远程暴露都会显著放大未授权访问风险,生产环境应配合 TLS(-H tcp://... 加证书)与网络隔离使用。后续版本中该能力演变为更精确的 --api-cors-header 白名单形式(可参考 api/docs/v1.24.md 中的相应说明)。
6. 从 v1.3 到当前代码库:端点的延续与查证路径
v1.3 文档并非孤本,它与同目录下的 api/docs/v1.0.md 至 api/docs/v1.24.md 构成完整的 API 版本演化档案,最新的规范以 OpenAPI 形式保存在 api/docs/v1.49.yaml。对照当前源码可以定位 v1.3 端点的现存实现:
- 路由注册:daemon/server/router/container/container.go(如
GET /containers/json的注册,见 daemon/server/router/container/container.go#L31); - 版本协商中间件的测试可参考 daemon/server/middleware/version_test.go,其请求路径
/containers/json与本文一致; - attach 劫持与多路复用:daemon/attach.go、client/hijack.go;
- 流式标准 I/O 编解码:api/pkg/stdcopy。
适用前提与限制:本文所有端点参数、响应样例与状态码均以 api/docs/v1.3.md 的 v1.3 规范为准,属于历史版本定义。例如 PortSpecs、images/viz 输出、POST /images/(name)/insert 等字段与端点在后续版本中已被移除或替换;若你的目标是编写对接现代 daemon 的客户端,应在理解 v1.3 设计思想(REST + 流式 hijacking)的基础上,以仓库内最新版本规范(如 api/docs/v1.49.yaml)核对当前签名。v1.3 文档的价值在于:它以最小集合展示了容器/镜像/系统三大类端点的完整形态,以及 attach 劫持这一贯穿至今的核心传输机制。
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 StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00