dagger 0.21.10 SDK 与 API 使用详解
dagger v0.21.10 SDK 与 API 实战:Python SDK 最小 module(hello/build/report 三函数)dagger call 跑通构建→输出全链路,本地 GraphQL 会话 API 直调、引擎容器生命周期实测与四类真实报错排障样本(2026-10-19 实测)。
dagger 0.21.10 SDK 与 API 使用详解
目标:用 Python SDK 写一个最小 dagger module 并通过
dagger call实测跑通"构建→输出"全链路,同时给出发动机般驱动引擎的本地 GraphQL 会话 API 直调方法、引擎生命周期实测结论与四类真实报错排障样本。2026-10-19 于 Ubuntu 22.04.4(dagger v0.21.10)实测,回显逐字照抄。
一、环境信息
- 操作系统:Ubuntu 22.04.4 LTS(x86_64),内核 6.8.0-138-generic
- dagger CLI / 引擎版本(实测回显):
dagger v0.21.10 (image://registry.dagger.io/engine:v0.21.10) linux/amd64
- SDK:Python SDK(随
dagger develop --sdk=python生成,本地落盘于模块sdk/目录,与引擎版本同源) - 实测模块:
/opt/workspace/dagger-demo(demo 模块,含 hello/build/report 三个函数) - 引擎实例:
dagger-engine-v0.21.10(容器运行时实例,组件本职形态,随用随起) - 受限网络说明:引擎实例已注入代理环境变量(注入方法与原因见第七章)
二、前置条件
本章说明调用 API 前需要就位的三件事:引擎、端点与认证、客户端工具。
- 引擎可用:CLI 首次执行任务时自动创建并启动引擎实例(实例名含版本号),无需手工部署;确认命令与实测回显:
docker ps -a --filter name=dagger-engine --format '{{.Names}} {{.Status}}'
dagger-engine-v0.21.10 Up 2 minutes
- API 端点与认证:引擎不暴露固定端口——每次 CLI/SDK 会话建立时,本地动态起一个 GraphQL 会话端点,凭据通过环境变量注入:
DAGGER_SESSION_PORT(端口)与DAGGER_SESSION_TOKEN(Bearer 认证)。手工获取端点的标准方式是dagger run包裹目标进程(见第六章实测),进程内直接读这两个变量即可。 - 客户端工具三选一:
dagger query(直发 GraphQL,免代码)、官方 SDK(Go/Python/TypeScript/Rust/Elixir/PHP,GitHub Release 提供sdk/<语言>/v0.21.10标签)、任意 HTTP 客户端(curl 等,走会话端点)。
三、API 总览
- 协议:GraphQL(HTTP POST,JSON 载荷);CLI 的
dagger call、dagger query与所有 SDK 最终都编译为对同一 API 的查询 - 版本约定:API 版本与引擎版本一致(本文 v0.21.10);模块的
dagger.json记录engineVersion作为兼容基线 - 认证:本地会话用
DAGGER_SESSION_TOKEN做 HTTP Basic/Bearer 认证(-u $DAGGER_SESSION_TOKEN:形式),无全局管理端口、无跨机暴露面,安全边界即本机 - 限流:本地 API 无限流约定;资源隔离由引擎的执行层与缓存层管理(v0.21.10 起支持可选的引擎 CPU/内存指标导出,见 Release Notes
telemetry.resourceMetrics) - 三种访问形态对比:
| 形态 | 适用 | 说明 |
|---|---|---|
dagger call | 日常调用模块函数 | 自动加载模块、渲染进度 |
dagger query | 调试 API 结构 | 手写 GraphQL,返回原始 JSON |
SDK / dagger run+HTTP | 把流水线写进应用代码 | 函数即代码,类型化客户端 |
四、SDK 接入与模块初始化
本章实测从零建模块到 Python SDK 就位的完整过程。初始化空模块:
mkdir -p /opt/workspace/dagger-demo && cd /opt/workspace/dagger-demo
dagger init --name demo
cat dagger.json
{
"name": "demo",
"engineVersion": "v0.21.10"
}
⚠️ 模块已存在时再执行 init 会报错(实测):
Error: module already exists。补装 SDK 用 develop。
接入 Python SDK(实测):
dagger develop --sdk=python --progress plain
10 : develop
11 : ┆ develop . DONE [2.3s]
10 : develop DONE [2.3s]
生成的关键文件(实测清单):
dagger.json:模块清单,sdk.source变为pythonpyproject.toml:模块工程文件,实测内容关键字段为requires-python = ">=3.14"、依赖dagger-io(以本地sdk/目录 editable 方式安装)
[project]
name = "demo"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = ["dagger-io"]
[build-system]
requires = ["uv_build>=0.8.4,<0.9.0"]
build-backend = "uv_build"
[tool.uv.sources]
dagger-io = { path = "sdk", editable = true }
解读:
requires-python >= 3.14由 SDK 运行时镜像保证,宿主机无需安装该版本 Python(模块函数跑在引擎管理的运行时里);dagger-io指向模块内sdk/目录,SDK 与引擎版本天然对齐。sdk/(SDK 源码与运行时)、src/demo/__init__.py与src/demo/main.py(函数实现入口)同步生成。
五、最小 module 实战:构建→输出全链路
本章给出可复制的最小 module(三个函数覆盖"纯计算、容器构建、构建后取产物"三种典型形态),并逐条实测调用。
5.1 函数实现(src/demo/main.py 全文,实测跑通)
import dagger
from dagger import dag, function, object_type
@object_type
class Demo:
@function
def hello(self, name: str) -> str:
"""返回一句问候语"""
return f"Hello, {name}!"
@function
def build(self, src: dagger.Directory) -> dagger.Container:
"""把源码目录挂进 alpine 容器,把 msg.txt 复制为 output.txt 并追加构建标记"""
return (
dag.container()
.from_("alpine:3.22")
.with_directory("/src", src)
.with_workdir("/src")
.with_exec(["sh", "-c", "cp msg.txt output.txt && echo built-by-dagger >> output.txt"])
)
@function
async def report(self, src: dagger.Directory) -> str:
"""构建并把输出文件内容作为字符串返回"""
return await self.build(src).file("/src/output.txt").contents()
结构解读:@object_type 把类注册进模块 schema;@function 声明可调用函数,类型注解即 API 类型(dagger.Directory/dagger.Container 是引擎的强类型对象);dag.container() 是 API 根入口,链式调用在引擎侧执行。函数间可直接互相调用(report 内部调用 self.build)。
5.2 准备源码与函数清单
echo 'hello from dagger module' > msg.txt
dagger functions -s
Name Description
build 把源码目录挂进 alpine 容器,把 msg.txt 复制为 output.txt 并追加构建标记
hello 返回一句问候语
report 构建并把输出文件内容作为字符串返回
5.3 逐函数实测
调用纯计算函数(实测):
dagger call hello --name dagger -s
Hello, dagger!
调用构建→返回内容链路(实测):
dagger call report --src . -s
hello from dagger module
built-by-dagger
构建产物导出为本地文件(实测,--output 保存 File/Directory 结果):
dagger call build --src . file --path /src/output.txt --output ./exported-output.txt -s
Saved to "/opt/workspace/dagger-demo/exported-output.txt".
cat exported-output.txt
hello from dagger module
built-by-dagger
至此最小 module 的"构建→输出"闭环跑通:
build返回容器对象、file --path链式取产物、--output落盘,全程无本地语言环境依赖。
六、会话 API 直调实测
本章不借助 SDK,用 HTTP 客户端直调引擎会话端点,验证 API 认证与调用协议。dagger run 包裹 curl,会话端口与令牌由 CLI 注入(实测一条命令复现官方帮助中的示例):
echo '{"query":"{ container { from(address: \"alpine:3.22\") { withExec(args: [\"echo\", \"api-works\"]) { stdout } } } }"}' | dagger run -s sh -c 'curl -s -u $DAGGER_SESSION_TOKEN: -H "content-type:application/json" -d @- http://127.0.0.1:$DAGGER_SESSION_PORT/query'
实测响应:
{"data":{"container":{"from":{"withExec":{"stdout":"api-works\n"}}}}}
同样的查询用 dagger query 直发(实测):
dagger query -s -M <<'EOF'
{ container { from(address: "alpine:3.22") { withExec(args: ["echo", "query-works"]) { stdout } } } }
EOF
{
"container": {
"from": {
"withExec": {
"stdout": "query-works\n"
}
}
}
}
错误响应长什么样(字段拼写错误,实测 422):
Error: make request: returned error 422: {"data":null,"errors":[{"message":"Cannot query field \"containr\" on type \"Query\". Did you mean \"container\"?","locations":[{"line":1,"column":3}],"extensions":{"code":"GRAPHQL_VALIDATION_FAILED"}}]}
结论:会话端点 = 标准 GraphQL over HTTP + Basic 认证;任何语言零依赖接入,SDK 只是把这套 API 类型化封装。
七、引擎生命周期与执行观测
引擎实例由 CLI 全自动管理,生命周期实测结论如下(实例名 dagger-engine-v0.21.10):
- 自动创建:本机无实例时,执行任意任务自动创建(CLI 进度日志实测出现
create container→exec docker start dagger-engine-v0.21.10)。 - 连接与会话:连接成功日志(实测):
INF connected name=55f142d61e1e client-version=v0.21.10 server-version=v0.21.10;随后starting session建立会话端点。 - 停止后自动拉起:手工停掉实例后执行查询,CLI 自动启动实例并完成任务(实测查询返回正常,事后实例状态
Up 2 seconds)。 - 删除后自动重建:删除实例后执行查询,CLI 按内嵌镜像地址重建,查询正常返回(实测)。
- 实例环境变量实测(
docker inspect节选):DAGGER_GO_SDK_MANIFEST_DIGEST=sha256:9ae7d4707fe9417d08503ab769c6d6101cc9f23c5f50a5a676f339885592b79b、DAGGER_PYTHON_SDK_MANIFEST_DIGEST=sha256:814d48c0cd65bd6e0a3232742614ab66d1c1489120f8ac585ede2b5d46d7d058、DAGGER_TYPESCRIPT_SDK_MANIFEST_DIGEST=sha256:2d26582288d350b6d6beea98dc7defc084d7d5ddccc42446cff5236e613、_EXPERIMENTAL_DAGGER_RUNNER_HOST=unix:///run/dagger/engine.sock——SDK 运行时镜像指纹在实例创建时即固化,保证函数执行环境可复现。 - 受限网络注意:实例被删除后 CLI 自动重建,但重建实例不带手工注入的代理变量(实测验证);需要代理的环境按第八章 Q1 手工重建。
八、常见报错排查(实测样本)
Q1:任务执行报镜像解析失败 connection refused(受限网络最常见)
实测原文:
Error: make request: input: container.from failed to resolve image "docker.io/library/hello-world:latest"
(platform: "linux/amd64"): failed to do request: Head
"https://registry-1.docker.io/v2/library/hello-world/manifests/latest": dial tcp 202.160.128.40:443:
connect: connection refused
原因与解决:引擎实例访问镜像源走自身网络栈,不走容器运行时守护进程的代理;手工重建实例注入代理(地址按实际环境替换):
docker rm -f dagger-engine-v0.21.10
docker run -d --name dagger-engine-v0.21.10 --privileged \
-e HTTP_PROXY=http://192.168.1.62:7897 \
-e HTTPS_PROXY=http://192.168.1.62:7897 \
-e NO_PROXY=localhost,127.0.0.1 \
registry.dagger.io/engine:v0.21.10
重建后重跑任务即恢复正常(实测 hello-world 查询成功返回完整 stdout)。
Q2:dagger call 报 unknown command "nope" for "dagger call"
实测原文:
Error: unknown command "nope" for "dagger call" [traceparent:bdd7e1bad9fef396be046cb3b5ab4c38-2ee3d63a3adf7713]
Run 'dagger call --help' for usage.
定位:同日志上方有 schema 概要(实测 query_function_count=3 query_functions="[build hello report]"),对照清单改函数名;若清单里没有目标函数,检查类是否标注 @object_type、函数是否标注 @function,改后重跑 dagger develop。
Q3:dagger query 返回 422 GRAPHQL_VALIDATION_FAILED
字段拼错即触发,错误体自带修正建议(实测样本见第六章末),按 "Did you mean" 修复。
Q4:dagger init 报 module already exists
目录已有 dagger.json 时 init 拒绝重初始化(实测);补装 SDK 走 dagger develop --sdk=<语言>,改模块名用 dagger config 或直接编辑 dagger.json。
九、注意事项
- 模块函数运行在引擎管理的运行时中,宿主机语言版本无关紧要(
requires-python >= 3.14由运行时镜像满足); - 函数签名即 API 契约:改参数/返回类型后必须重跑
dagger develop重新生成 schema; - 敏感值用引擎的 Secret 类型传递,避免进入日志与缓存明文;
dagger.json的engineVersion是兼容基线,升级 CLI 后重跑dagger develop对齐;- 会话端点随会话生灭(端口动态分配),不要硬编码;需要长连进程统一用
dagger run包裹。
十、参考链接
- Python SDK 模块开发文档:https://docs.dagger.io/0.21(SDKs 章节)
- v0.21.10 Release Notes(engine 遥测等):https://github.com/dagger/dagger/releases/tag/v0.21.10
- SDK Release 标签(Go/Python/TypeScript/Rust/Elixir/PHP):https://github.com/dagger/dagger/releases
- 本系列姊妹篇:《dagger 0.21.10 介绍与选型指南》《Ubuntu 22.04 安装 dagger 0.21.10 指南》《dagger 0.21.10 常用 CLI 命令与工具详解》