当前位置: 首页
AI教程
如何将本地自定义sandbox-extra镜像推送到Daytona沙盒Snapshot列表

如何将本地自定义sandbox-extra镜像推送到Daytona沙盒Snapshot列表

时间:2026-08-17
转载

本地构建sandbox-extra镜像后推送至Registry,通过API或WebDashboard创建Snapshot。关键注意容器内部网络需使用registry:6000地址,避免连接拒绝;需用JWTToken而非APIKey获取权限;Dex不支持密码模式,需通过Web或设备码认证。相同名称不可重复创建,失败需先删除。

Sandbox Extra 镜像推送与升级指南

在搭建好 Daytona 环境之后,下一个关键动作就是把自定义的 Sandbox Extra 镜像推送上去并创建 Snapshot。这事儿说复杂不复杂,但里面的坑确实不少——尤其是当你从宿主机视角切换到容器内部网络视角的时候,稍不留神就会遇到“连接被拒绝”的报错。

这篇文章会把整个流程拆开来讲,包括三种不同的操作方式、四个典型踩坑记录,以及后续升级镜像的标准操作流程。无论你是第一次操作还是需要排查问题,应该都能找到答案。

1. 整体流程概览

先在大脑里过一遍整体链路:

  • 本地构建好 sandbox-extra:0.1 镜像
  • 给它打上 Registry 标签(localhost:6000/...)
  • 通过 docker push 推送到本地 Registry
  • 通过 API 或 Web Dashboard 创建 Snapshot
  • Runner 从 Registry 拉取镜像,Snapshot 状态变为 active

整个流程看起来清晰,但关键点在于:Runner 所在的容器网络里,Registry 地址怎么写。这一点会在后面的“踩坑记录”里详细展开。

2. 前置准备与关键参数

2.1 环境信息

动手之前,先把环境里的几个核心参数确认好:

参数值
Daytona API 地址http://localhost:3000
Registry 地址(宿主机)localhost:6000
Registry 地址(容器内部)registry:6000 ← 关键!
Registry 登录admin / password
Registry 项目daytona
组织 ID (Organization ID)9038b0ab-b214-46d2-a14e-d2113ecf2fd4
Dex OIDC 地址http://localhost:5556/dex
Web Dashboardhttp://localhost:3000/dashboard

2.2 认证凭据

Web 登录账号:dev@daytona.io / password
API Key:dtn_b4b9e38cfcc3677bae7d72dc0812ecf7dacdb5534789e9ce2d1b89bf605d1132

3. 方式一:通过 Daytona API 创建 Snapshot(推荐)

如果你习惯用命令行操作,这种方式是最灵活的。

3.1 获取 JWT Token

Daytona 使用 Dex 做 OIDC 认证,获取 JWT Token 有两种方式。

本地构建的自定义sandbox-extra镜像推送到沙盒daytona的snapshot列表中

方法 A:通过 Web 登录获取(最简单)

  1. 打开浏览器访问 http://localhost:3000/dashboard
  2. 用 dev@daytona.io / password 登录
  3. 登录后从浏览器开发者工具中复制 JWT Token:
    • F12 → Application → Local Storage → 找到 token
    • 或者在 API 请求头中复制 Authorization: Bearer xxx

方法 B:通过 Device Code Flow(命令行)

第一步,获取设备认证码:

curl -s -X POST http://localhost:5556/dex/device/code \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=daytona&scope=openid%20profile%20email"

第二步,浏览器打开返回的 verification_uri_complete 链接,用 dev@daytona.io 登录。第三步,轮询获取 token:

curl -s -X POST http://localhost:5556/dex/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
  -d "device_code=xxx" \
  -d "client_id=daytona"

3.2 验证 Token

拿到 JWT Token 后,先验证一下是否有效,顺便确认组织 ID:

curl -s http://localhost:3000/api/organizations \
  -H "Authorization: Bearer " | jq .

返回的示例:[ { "id": "9038b0ab-b214-46d2-a14e-d2113ecf2fd4", "name": "Personal", ... } ]

3.3 推送镜像到本地 Registry

docker tag sandbox-extra:0.1 localhost:6000/daytona/sandbox-extra:0.1
docker push localhost:6000/daytona/sandbox-extra:0.1

3.4 创建 Snapshot

这是核心步骤,注意 imageName 字段使用的是容器内部的 Registry 地址:

TOKEN=""
ORG_ID="9038b0ab-b214-46d2-a14e-d2113ecf2fd4"

curl -s -X POST http://localhost:3000/api/snapshots \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Daytona-Organization-ID: $ORG_ID" \
  -d '{
    "name": "sandbox-extra",
    "imageName": "registry:6000/daytona/sandbox-extra:0.1",
    "cpu": 2,
    "memory": 4,
    "disk": 10,
    "sandboxClass": "container"
  }' | jq .

参数说明:

参数说明建议值
nameSnapshot 名称,唯一标识sandbox-extra
imageName容器内部 Registry 地址registry:6000/daytona/sandbox-extra:0.1
cpuSandbox 分配的 CPU 核数2
memory内存大小 (GB)4
disk磁盘大小 (GB)10
sandboxClassSandbox 类型container

3.5 查看 Snapshot 状态

curl -s http://localhost:3000/api/snapshots \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Daytona-Organization-ID: $ORG_ID" | jq '.items[] | {name, state, size, errorReason}'

状态流转很清楚:pending → pulling → active(成功),或者 pending → pulling → error(失败,查看 errorReason)。

3.6 删除 Snapshot(如需重试)

SNAPSHOT_ID=""
curl -s -X DELETE "http://localhost:3000/api/snapshots/$SNAPSHOT_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Daytona-Organization-ID: $ORG_ID"

4. 方式二:通过 Web Dashboard 操作

如果你更倾向于图形界面操作,Dashboard 也完全可以完成。

4.1 登录 Dashboard

浏览器打开 http://localhost:3000/dashboard,使用 dev@daytona.io / password 登录。Dex 会重定向回 Dashboard。

4.2 推送镜像到 Registry(前提)

无论哪种方式,都需要先将镜像推送到本地 Registry:

docker tag sandbox-extra:0.1 localhost:6000/daytona/sandbox-extra:0.1
docker push localhost:6000/daytona/sandbox-extra:0.1

4.3 通过界面创建 Snapshot

登录 Dashboard 后,找到 Snapshots(快照)管理页面。点击 Create Snapshot(创建快照),填写以下信息:

  • Name: sandbox-extra
  • Image Name: registry:6000/daytona/sandbox-extra:0.1(⚠️ 必须用容器内部地址 registry:6000)
  • CPU / Memory / Disk: 按需设置

点击 Create 后,等待状态从 pending → pulling → active 即可。

4.4 Registry UI 查看镜像

通过 http://localhost:5100 可以查看 Registry UI,确认 daytona/sandbox-extra 仓库及其标签是否已经推送成功。

5. 方式三:通过 Daytona CLI 操作(开发中)

Daytona CLI(daytona)当前版本(v0.190.0)主要用于服务端管理和 Sandbox 交互,暂未提供直接的 snapshot 管理命令。可以通过 daytona --help 查看可用命令。如果需要从 CLI 操作,建议使用 curl 封装脚本(见方式一)。

6. 踩坑记录

实际操作中,下面这几个坑几乎是绕不过去的,提前了解一下能节省不少排查时间。

坑 1:localhost:6000 vs registry:6000(最重要!)

❌ 错误做法:

"imageName": "localhost:6000/daytona/sandbox-extra:0.1"

报错信息:

Snapshot localhost:6000/daytona/sandbox-extra:0.1 failed to inspect in registry.
Error: Error response from daemon: Get "http://localhost:6000/v2/":
dial tcp [::1]:6000: connect: connection refused

✅ 正确做法:

"imageName": "registry:6000/daytona/sandbox-extra:0.1"

原因分析:

宿主机视角下,localhost:6000 可以访问到 Registry。但 Runner 跑在容器里,localhost:6000 指向的是 Runner 容器本身,而 Runner 自己显然没有 Registry 服务,所以连接被拒绝。正确的方式是使用 Docker DNS 内部网络的服务名 registry,这样容器间才能正常通信。

坑 2:API Key 权限不足

❌ 错误做法: 直接用 API Key 调用 POST /api/snapshots

Authorization: Bearer dtn_b4b9e38cfcc3677bae7d72dc0812ecf7dacdb5534789e9ce2d1b89bf605d1132

报错信息:403 Forbidden: Access denied

原因: 创建 snapshot 需要 write:snapshots 权限,而 API Key 默认可能没有此权限。✅ 解决办法:使用 JWT Token(通过 Web 登录获取)代替 API Key。

坑 3:Dex 不支持 password grant type

❌ 错误做法:

curl -X POST http://localhost:5556/dex/token \
  -d "grant_type=password&client_id=daytona&username=dev@daytona.io&password=password"

报错信息:{ "error": "unsupported_grant_type" }

原因: Dex 配置中未启用 password grant type,只支持 urn:ietf:params:oauth:grant-type:device_code(设备码)和 urn:ietf:params:oauth:grant-type:token-exchange(令牌交换)。✅ 解决办法:通过 Web 登录获取 JWT,或使用 Device Code Flow。

坑 4:相同的 name 不能重复创建

第一次失败后,需要先删除再重新创建,否则会直接失败。

7. 后续升级镜像的标准操作流程

当你构建了新的 sandbox-extra:0.2 版本时,按以下步骤操作即可。

Step 1: 构建新版本镜像

cd /root/daytona-sandbox-extra
./build.sh

Step 2: 推送新版本到 Registry

docker tag sandbox-extra:0.2 localhost:6000/daytona/sandbox-extra:0.2
docker push localhost:6000/daytona/sandbox-extra:0.2

Step 3: 通过 Dashboard 创建新 Snapshot

登录 http://localhost:3000/dashboard → 进入 Snapshots 管理页面 → 点击 Create Snapshot → 填写 Name(如 sandbox-extra-v2)、Image Name(registry:6000/daytona/sandbox-extra:0.2)、资源配额 → 创建,等待状态变为 active。

Step 4(可选): 通过 API 创建

JWT="<你的JWT Token>"
ORG_ID="9038b0ab-b214-46d2-a14e-d2113ecf2fd4"

curl -s -X POST http://localhost:3000/api/snapshots \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -H "X-Daytona-Organization-ID: $ORG_ID" \
  -d '{
    "name": "sandbox-extra-v2",
    "imageName": "registry:6000/daytona/sandbox-extra:0.2",
    "cpu": 2,
    "memory": 4,
    "disk": 10,
    "sandboxClass": "container"
  }' | jq .

完整一键脚本

#!/bin/bash
# file: /root/daytona/docker/push-sandbox-extra.sh

set -e
VERSION="${1:-0.1}"
JWT="$JWT_TOKEN"  # 先 export JWT_TOKEN=...
ORG_ID="9038b0ab-b214-46d2-a14e-d2113ecf2fd4"

echo "=== 1. 打标签 ==="
docker tag sandbox-extra:${VERSION} localhost:6000/daytona/sandbox-extra:${VERSION}

echo "=== 2. 推送镜像 ==="
docker push localhost:6000/daytona/sandbox-extra:${VERSION}

echo "=== 3. 创建 Snapshot ==="
curl -s -X POST http://localhost:3000/api/snapshots \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -H "X-Daytona-Organization-ID: $ORG_ID" \
  -d "{
    \"name\": \"sandbox-extra-v${VERSION}\",
    \"imageName\": \"registry:6000/daytona/sandbox-extra:${VERSION}\",
    \"cpu\": 2,
    \"memory\": 4,
    \"disk\": 10,
    \"sandboxClass\": \"container\"
  }" | jq .

echo "=== 4. 等待拉取完成 ==="
sleep 5
curl -s http://localhost:3000/api/snapshots \
  -H "Authorization: Bearer $JWT" \
  -H "X-Daytona-Organization-ID: $ORG_ID" | jq '.items[] | {name, state, size, errorReason}'

使用方法:

export JWT_TOKEN="eyJxxxxx"
bash /root/daytona/docker/push-sandbox-extra.sh 0.2

8. 常见问题 FAQ

Q: 创建 snapshot 后一直卡在 pending 状态?

A: 检查 runner 是否正常运行:docker ps | grep runner。runner 负责拉取镜像,如果它没在工作,Snapshot 自然无法推进。

Q: 状态变为 error,错误信息包含 "connection refused"?

A: 镜像地址使用了 localhost:6000,应改为 registry:6000。详情见坑 1。

Q: API 返回 401 Unauthorized?

A: Token 可能已过期。JWT Token 有效期约 24 小时,过期后重新通过 Web 登录获取。

Q: API 返回 403 Forbidden?

A: 改用 JWT Token 而不是 API Key。详情见坑 2。

Q: 如何获取 Organization ID?

A: 调 GET /api/organizations 接口:

curl -s http://localhost:3000/api/organizations \
  -H "Authorization: Bearer $JWT" | jq '.[0].id'

Q: Registry 里有哪些镜像?

A: 通过 Registry API 查看:

# 查看所有仓库
curl -s http://localhost:6000/v2/_catalog | jq .
# 查看特定仓库的标签
curl -s http://localhost:6000/v2/daytona/sandbox-extra/tags/list | jq .

Q: 如何查看 Runner 的日志排查问题?

A: docker logs daytona-runner-1 --tail 50

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
CAD零基础入门教程:坐标输入、图层管理与基础绘图命令

CAD零基础入门教程:坐标输入、图层管理与基础绘图命令

本文面向CAD零基础学习者,系统讲解坐标输入、图层管理与基础绘图命令的核心用法。通过分步实操与常见问题排查,帮助新手建立精确绘图习惯,掌握规范出图的基础能力。

时间:2026-09-01 16:53
CAD从入门到项目交付:绘图、标注、图块与实战工作流

CAD从入门到项目交付:绘图、标注、图块与实战工作流

掌握CAD的核心在于建立“画得准、标得清、复用快、交付稳”的工作流。本文提供从环境设置、高频命令组合、标注规范、图块标准化到项目分阶段交付的完整路径,帮助初学者避免常见返工陷阱,独立完成可检查、可复用、可打印的工程图纸。

时间:2026-09-01 16:52
Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤

Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤

本文详细解析 Claude Code 登录前的账号类型区分方法,涵盖个人订阅、Teams 席位与企业 Enterprise 席位的授权路径差异。提供终端登录命令、环境变量排查及常见异常处理步骤,帮助用户快速完成正确授权并避免登录路径混淆。

时间:2026-09-01 14:27
Claude Code 文件修改前的权限模式配置与命令审批指南

Claude Code 文件修改前的权限模式配置与命令审批指南

本文详细介绍Claude Code在修改文件前的权限模式配置方法,包括defaultMode可选值、permissions allow与deny规则设置、多层级配置文件管理以及 status验证技巧,帮助开发者安全高效地使用AI编程助手。

时间:2026-09-01 14:12
Claude Code接入VS Code后先测扩展和终端命令

Claude Code接入VS Code后先测扩展和终端命令

在VS Code中接入Claude Code后,建议优先验证扩展面板与集成终端两条入口。本文提供标准检查顺序、关键命令与常见故障排查路径,帮助你快速确认环境就绪,避免后续开发受阻。

时间:2026-09-01 14:10
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全