菜单

运行时构建

相关源文件

本文档涵盖了用于为 OpenHands Agent 创建沙盒运行时环境的 Docker 镜像构建系统。运行时构建过程通过从模板动态生成 Dockerfile,使用镜像分层策略实现构建优化,并支持本地 Docker 构建和基于远程 API 的构建。

有关这些构建的运行时镜像在执行期间如何使用的信息,请参阅 运行时实现。有关在这些镜像内部运行的操作执行服务器的详细信息,请参阅 操作执行服务器

构建过程概述

运行时构建系统通过多阶段流程将基础 Docker 镜像转换为完全配置的 OpenHands 运行时环境,该流程涉及模板渲染、构建上下文准备和优化镜像构建。

构建流程

来源:openhands/runtime/utils/runtime_build.py105-158 openhands/runtime/utils/runtime_build.py161-246 openhands/runtime/builder/docker.py51-246 openhands/runtime/builder/remote.py28-121

构建优化策略

该系统通过 BuildFromImageType 枚举实现三种构建策略,以优化构建时间和镜像复用。

策略基础镜像用例构建时间
SCRATCH原始基础镜像首次构建,强制重新构建最慢
VERSIONED最新同版本镜像版本升级中等
LOCK精确依赖匹配仅源代码更改最快

构建策略选择逻辑

来源:openhands/runtime/utils/runtime_build.py206-246 openhands/runtime/utils/runtime_build.py21-25

Dockerfile 模板系统

运行时构建过程使用 Jinja2 模板根据构建策略和基础镜像特性动态生成 Dockerfile。

模板宏和渲染

Dockerfile.j2 模板为不同的构建阶段定义了几个宏:

  • setup_base_system() - 安装系统依赖、Node.js、Python 和 Poetry。
  • setup_vscode_server() - 下载并配置 OpenVSCode Server。
  • install_vscode_extensions() - 安装自定义 VSCode 扩展。
  • install_dependencies() - 通过 Poetry 和 Micromamba 安装 Python 依赖。

_generate_dockerfile() 中的模板渲染过程根据构建参数有条件地包含这些宏。

来源:openhands/runtime/utils/runtime_templates/Dockerfile.j21-190 openhands/runtime/utils/runtime_build.py31-59

运行时构建器架构

构建器系统使用抽象基类模式来支持多个构建后端。

来源:openhands/runtime/builder/base.py4-43 openhands/runtime/builder/docker.py16-419 openhands/runtime/builder/remote.py19-150

Docker 构建实现

DockerRuntimeBuilder 通过 docker buildx 命令使用 Docker BuildKit 执行构建。

构建流程详解

  1. 版本验证:确保 Docker/Podman 版本兼容性。
  2. BuildKit 设置:配置 BuildKit 以提高构建性能。
  3. 构建执行:运行 docker buildx build 并进行进度监控。
  4. 缓存管理:可以选择使用本地构建缓存以加快重新构建速度。
  5. 镜像标记:为不同的优化级别应用多个标签。

构建命令结构

来源:openhands/runtime/builder/docker.py129-156 openhands/runtime/builder/docker.py170-221

远程构建实现

RemoteRuntimeBuilder 通过 HTTP API 将构建任务卸载到远程服务。

远程构建流程

来源:openhands/runtime/builder/remote.py35-121 openhands/runtime/builder/remote.py122-149

镜像标记和哈希系统

运行时构建系统实施了复杂的标记策略以优化镜像复用。

哈希生成函数

  • get_hash_for_lock_files() - 从 pyproject.tomlpoetry.lock 以及基础镜像生成哈希。
  • get_hash_for_source_files() - 从整个 OpenHands 源代码目录创建哈希。
  • get_tag_for_versioned_image() - 规范化基础镜像名称以用于版本化标记。
  • truncate_hash() - 将 MD5 十六进制转换为 base36 以缩短标记名称。

标记命名约定

{repo}:oh_v{version}_{lock_hash}_{source_hash}  # Primary tag
{repo}:oh_v{version}_{lock_hash}                # Lock reuse tag  
{repo}:oh_v{version}_{versioned_tag}            # Version reuse tag

来源:openhands/runtime/utils/runtime_build.py304-339 openhands/runtime/utils/runtime_build.py171-179 openhands/runtime/utils/runtime_build.py294-301

构建上下文准备

prep_build_folder() 函数通过复制源代码文件和生成 Dockerfile 来组装 Docker 构建上下文。

构建上下文结构

build_folder/
├── code/
│   ├── openhands/           # Source code (filtered)
│   ├── pyproject.toml       # Poetry project file
│   └── poetry.lock          # Dependency lock file
└── Dockerfile               # Generated from template

源代码复制过程会排除开发工件。

  • 隐藏目录(.*/*
  • Python 缓存(__pycache__/*.pyc
  • 文档文件(*.md

来源: openhands/runtime/utils/runtime_build.py249-289 openhands/runtime/utils/runtime_build.py262-271

配置与环境

运行时构建集成了更广泛的 OpenHands 配置系统

  • 镜像仓库配置:通过 OH_RUNTIME_RUNTIME_IMAGE_REPO 环境变量
  • 构建参数:接受额外的依赖和构建参数
  • 平台支持:通过 --platform 标志进行跨平台构建
  • 缓存控制:可配置的本地构建缓存使用

默认的镜像仓库是 ghcr.io/all-hands-ai/runtime,但可以为自定义部署进行覆盖。

来源: openhands/runtime/utils/runtime_build.py27-29 containers/runtime/config.sh1-8 openhands/runtime/builder/docker.py144-151