☰
IB_Robot 容器验证排障手册:Ubuntu Docker 中 setup.sh / build.sh 的 21 个已知陷阱与修复实践
2026/10/14 2:06:17 网站建设 项目流程
  • 具身智能
  • 机器人
  • 人工智能
  • 大模型
  • 模型推理服务
  • 本地部署
  • 计算机视觉
  • ROS

【免费下载链接】IB_Robot

Save the code of IB-Robot, an AI robot execution framework developed by openEuler Embedded for embodied intelligence scenarios. It includes references to the forked version of tensormsg, references to lerobot fork, code references to the lerobot_ros2:ros2_ws branch, as well as some code related to development usability.

项目地址:https://gitcode.com/openeuler/IB_Robot
点击查看免费下载

本文面向需要实际执行 IB_Robot 干净环境验证的开发者与 CI 维护者,系统梳理在osrf/ros:humble-desktop-full-jammyDocker 容器中运行scripts/setup.sh与scripts/build.sh时已知的 21 个典型故障:每条均给出可复现的症状、根因分析、精确修复动作,并回落到仓库源码与验证流程文档中的对应实现,帮助读者从"看到报错"快速走到"理解机制、一次修复"。

引言:陷阱清单在验证流程中的定位

IB_Robot 的 Ubuntu Docker 验证流程(skill 定义见 .agents/skills/ibrobot-docker-verify/SKILL.md)在干净容器中端到端执行setup.sh+build.sh,目标是证明"按脚本安装即可复现构建"。该流程遵循一条核心纪律(完整论述见 .agents/skills/ibrobot-docker-verify/references/discipline.md):

setup.sh和build.sh是唯一合法的软件安装途径。

即:禁止在容器中手动apt install/pip install、禁止sedpatch 容器内脚本、禁止手动配置 ROS 仓库;只允许配置 apt 镜像源、创建用户、通过环境变量传递镜像 URL、挂载宿主机 pip 缓存与 CUDA 工具链。所有"绕过脚本"的操作都会让验证结果失去意义。

验证按 Phase 0~6 推进(完整命令见 .agents/skills/ibrobot-docker-verify/references/procedure.md):

Phase目的关键产出
0宿主机前置检查(docker、uid、pip 缓存、CUDA)PROJECT_ROOT、HOST_UID、HOST_PIP_CACHE
1拉取osrf/ros:humble-desktop-full-jammy镜像IMAGE_SECONDS
2创建容器、配置镜像源、创建testuser、验证缓存可写CONTAINER_SECONDS
3准备源码工作区(三种 source mode 择一)SOURCE_MODE、SOURCE_DETAILS
3.5ROS 源切换预清理(条件执行)容器内无ros-*残留
4运行setup.sh --yes并计时/tmp/setup.log、SETUP_ELAPSED_SECONDS
5运行build.sh并计时/tmp/build.log、BUILD_ELAPSED_SECONDS
6收集 ERROR 行、汇总计时、清理容器最终报告

验证通过的标准是日志出现Setup complete! Run ./scripts/build.sh to build the workspace.与Build complete. Source with: source install/setup.sh;任何 ERROR 行都必须逐条列出并归入Fatal(脚本未输出完成消息、进程异常退出,阻塞)或Non-fatal(pip resolver 警告、rosdep keys 未解析等,不阻塞)两类。

容器命名约定固定如下(SKILL.md):

变量值
容器名verify-ubuntu2204
用户testuser
工作区/home/testuser/IB_Robot
镜像osrf/ros:humble-desktop-full-jammy
pip 缓存挂载点/var/cache/ibrobot-pip

下面按故障主题将 21 个已知陷阱(原始清单见 .agents/skills/ibrobot-docker-verify/references/pitfalls.md)分组展开。

用户、权限与缓存类陷阱

这一组故障的共同根因是:docker exec无 TTY、docker cp保留宿主 UID/GID、bind mount 由 root 预创建父目录。它们发生在任何软件安装之前,但会让后续 setup 直接失败。

1.sudo: a terminal is required to read the password

症状容器内 sudo 相关命令报"需要终端读取密码"
原因Docker exec 分离模式不分配 tty;Ubuntu 22.04 默认 sudoers 开启use_pty,使sudo -v即便在拥有NOPASSWD:ALL时也要求终端
修复Phase 2.3 必须写入testuser ALL=(ALL) NOPASSWD:ALL

源码佐证在 scripts/setup/common.sh:ensure_sudo_session先尝试非交互的sudo -n true,失败才回退到需要终端的sudo -v。分离模式下没有终端可用,所以容器必须配NOPASSWD:ALL,让sudo -n true直接成功;否则ensure_sudo_session在sudo -n true返回非零时即失败——此时既无 NOPASSWD 也无缓存凭证可依赖,流程在[INFO] Sudo authentication required...之后中断。

2.Permission denied: ~/.cache/pre-commit

症状pre-commit 读取~/.cache时 Permission denied
原因bind mount 使 Docker 以 root 预创建了 home 缓存父目录(发生在useradd之前),导致testuser无访问权
修复pip 缓存挂载到/var/cache/ibrobot-pip,不要挂载到~/.cache之下

对应 procedure.md Phase 2 的--mount "type=bind,src=${HOST_PIP_CACHE},dst=/var/cache/ibrobot-pip"。即使 pip 目录本身可写,~/.cache父目录的属主错误也会破坏 pre-commit 等工具,因此挂载点选择本身就是防错设计。

3.pip cache has been disabled

症状pip 报告"cache has been disabled"
原因容器 UID/GID 与宿主缓存属主不匹配,通常是1000:1000被硬编码
修复用宿主机id -u/id -g重建testuser,并在 setup 前强制用户级写探针

Phase 0 要求HOST_UID=$(id -u)、HOST_GID=$(id -g)(procedure.md),Phase 2.3 据此useradd -m -u "${HOST_UID}" -g ... testuser。Phase 2.4 的缓存写探针必须以testuser身份执行(root 的test -w会产生对他人属主目录的假阳性),创建并删除PIP_CACHE_DIR/.ibrobot-write-test-$$探针文件;探针失败即终止验证,禁止通过把宿主缓存改为 world-writable 来绕过。Phase 4 中若setup.log仍出现cache has been disabled,则按基础设施错误判定验证无效、计时不可信。

4.fatal: detected dubious ownership in repository ...

症状后续 git 探针(如 Phase 6 的git rev-parseprovenance 行)报 dubious ownership
原因docker cp保留宿主 UID;容器用户对复制的仓库没有safe.directory记录
修复Phase 2.3b 在useradd后立即把/home/testuser/IB_Robot注册为testuser的 gitsafe.directory

原始记录(2026-09):报告步骤原本应输出 HEAD/tree,却因该错误中断。修复命令为:

docker exec -u testuser -e HOME=/home/testuser "${CONTAINER}" \ git config --global --add safe.directory /home/testuser/IB_Robot

注意 openEuler 变体使用通配符safe.directory "*",因为其工作区每个子模块都是独立 git 仓库;Ubuntu 侧按需追加即可(详见 .agents/skills/ibrobot-docker-verify-oee/references/pitfalls.md 对照)。

网络与镜像类陷阱

这一组故障集中在rosdep 工具链与 apt/pip 下载源上。IB_Robot 的 setup 脚本已将国内镜像设为默认值(scripts/setup.sh):

环境变量默认值
SETUP_ROSDISTRO_INDEX_URLhttps://mirrors.tuna.tsinghua.edu.cn/rosdistro/index-v4.yaml
SETUP_ROSDEP_DEFAULT_SOURCES_URLhttps://mirrors.tuna.tsinghua.edu.cn/github-raw/ros/rosdistro/master/rosdep/sources.list.d/20-default.list
SETUP_PIP_INDEX_URLhttps://repo.huaweicloud.com/repository/pypi/simple/
SETUP_PIP_TRUSTED_HOSTrepo.huaweicloud.com

5.sh: 1: rosdep: not found

症状脚本调用 rosdep 时报 not found
原因rosdepc 内部调用os.system('rosdep ...')导致找不到命令
修复弃用 rosdepc,改为直接pip install rosdep

对应 scripts/setup/rosdep.sh 的ensure_rosdep:先确认 workspace venv 存在(ensure_workspace_venv),再"${VENV_PYTHON}" -m pip install --ignore-installed --upgrade rosdep,并验证${VENV_PATH}/bin/rosdep --version可用;ROSDEP_BIN固定指向 venv 内可执行文件,避免 PATH 与 os.system 子进程环境不一致。

6.error loading sources list: Permission denied

症状rosdep 初始化加载 sources list 时权限拒绝
原因write_rosdep_sources_list曾以 600 权限 root 属主写文件
修复写完后chmod 644

源码见 scripts/setup/rosdep.sh:先用run_sudo mkdir -p保证/etc/ros/rosdep/sources.list.d存在,通过download_default_sources_list下载内容到临时文件,run_sudo mv就位后run_sudo chmod 644 "${target_file}"。644 是保证普通用户可读的关键权限位,此后rosdep_sources_list_needs_refresh用 grep 判断是否仍指向 raw.githubusercontent 旧源来决定是否重写。

7.rosdep update超时

症状rosdep update长时间无响应后超时
原因ROSDISTRO_INDEX_URL未被传入平台脚本
修复平台脚本显式env ROSDISTRO_INDEX_URL=...传递

setup.sh 的platform_install_rosdeps中(scripts/setup.sh)固定以env ROSDISTRO_INDEX_URL="${SETUP_ROSDISTRO_INDEX_URL}" "${rosdep_cmd}" update --rosdistro=humble调用,把 TUNA 索引 URL 传递给 rosdep;同时ensure_python_ssl_cert_file会为 Python 设置SSL_CERT_FILE/PYTHONHTTPSVERIFY,规避 HTTPS 证书失败导致的静默超时(scripts/setup/rosdep.sh)。

8. pip 从 pypi.org 下载仅约 10 KB/s

症状容器内 pip 直连 pypi.org 极慢
原因容器内未配置 pip 镜像
修复ensure_workspace_venv向${VENV_PATH}/pip.conf写入镜像配置

源码见 scripts/setup/rosdep.sh:venv 创建后立即生成pip.conf:

[global] index-url = ${SETUP_PIP_INDEX_URL} trusted-host = ${SETUP_PIP_TRUSTED_HOST}

因为该文件位于 venv 内部而非~/.config/pip,即使容器用户与宿主 UID 不一致也能被 pip 正确读取。

9. rosdep 从packages.ros.org下载约 10 KB/s

症状rosdep 安装依赖时命中官方 ROS 源,速度极慢
原因ROS desktop-full 镜像保留了 deb822 格式的ros2.sources文件
修复Phase 2 在apt-get update前把.sources与.list两套 ROS 条目统一切到 TUNA

Phase 2.2 的 sed 同时处理ros2.sources(deb822)与旧式ros2.list两种格式,将packages.ros.org/ros2/ubuntu替换为https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu,并在替换后 grep 校验确认无官方源残留,否则 exit 1(procedure.md)。apt 镜像源切换(Aliyun)属允许的容器环境初始化,不算手动安装软件。

10. TUNA ROS 源索引返回 404

症状apt-get update访问 TUNA ROS 源时 404
原因TUNA 只提供二进制 ROS 包,不提供deb-src索引
修复Phase 2 把 deb822 的Types: deb deb-src改为Types: deb,并删除传统deb-src条目

对应 Phase 2.2 的 sed 规则s|^Types: deb deb-src$|Types: deb|与/^deb-src /d。这是"镜像可用但格式不兼容"的典型场景,误判为网络故障会浪费排查时间。

源码准备与构建工具链类陷阱

这一组故障发生在工作区拷贝、venv 复用、git 工具链与 CUDA 扩展编译环节。Phase 3 的三种 source mode(独立 commit 快照 / 本地工作区拷贝 / 显式远端 clone)都必须执行同一动作:

rm -rf /home/testuser/IB_Robot/{venv,build,install,log}

即禁止复用宿主或上次运行遗留的 venv 与构建产物——这是多条陷阱的共同防线。

11.The build time path ... doesn't exist

症状build 报"构建时路径不存在"
原因拷贝或迭代式源码保留了宿主专属的 venv/构建路径
修复删除venv build install log后,从所选 source 重新执行 setup

这条直接对应上面的清理命令。工作区只允许"代码"进入容器,任何记录绝对路径的元数据(venv 内脚本、build 缓存、install 布局)都会在 UID/路径双重变化后失效。

12.git: command not found中途失败

症状setup 进行到一半时 git 命令丢失
原因install_ros.sh的 apt 安装可能移除 git
修复Phase 1 已装 git;必要时重跑apt-get install -y git git-lfs

镜像初始 bootstrap 阶段(Phase 2.2)即安装sudo git git-lfs locales python3 curl gnupg2 lsb-release software-properties-common;若中途仍丢失,按修复动作补装后重跑。这与 scripts/setup/submodules.sh 中大量git -C ...子模块操作强相关——git 缺失会让子模块初始化阶段直接中断。

13. lerobot patch 栈拉取失败

症状LeRobot patch 应用时 fetch 失败
原因子模块本地 checkout 不含所需 base commit
修复先把分支 rebase 到upstream/master再拷贝

源码侧的完整契约见 scripts/setup/lerobot_patches.sh 的_lerobot_ensure_base_commit:若git cat-file -e "${base_commit}^{commit}"失败,会尝试从 manifest 声明的 upstream 仓库 fetch 对应 tag 或 commit。base commit 通过third_party/patches/lerobot/INDEX.yaml的 active_tag 解析,并受 manifestlerobot_commit_range的 fail-closed 校验约束(HEAD 必须落在范围内)。验证流程用IBR_LEROBOT_FORCE_REBUILD=1强制在容器内从记录的上游 base 重建 patch 分支,规避本地 checkout 漂移。

14.GraspGen pointnet2_ops requires a CUDA toolkit

症状GraspGen 安装要求 CUDA toolkit
原因宿主无 CUDA toolkit
修复Phase 0 检测 nvcc;缺失时 setup.sh 优雅跳过 grasp 安装(仿SAM2_BUILD_CUDA=0模式),验证在无 grasp smoke test 的情况下继续

Phase 0 用command -v nvcc或/usr/local/cuda/bin/nvcc探测宿主(procedure.md),检测失败仅告警并清空HOST_CUDA_HOME。对应源码见 scripts/setup/python_venv.sh 与 scripts/setup/install_graspgen_pip.sh:check_graspgen_cuda_toolkit依次探测CUDA_HOME/bin/nvcc、/usr/local/cuda-<torch_cuda_version>、PATH 上的 nvcc;全部缺失则回退到third_party/wheels/pointnet2_ops下 ABI 绑定 Python 3.10 + Torch 2.7.1+cu126 的预编译 wheel(校验 SHA256SUMS)。而pointnet2_ops编译使用固定的TORCH_CUDA_ARCH_LIST(默认 8.6,见 install_graspgen_pip.sh),不需要--gpus透传,smoke test 仅做importlib.util.find_spec。

15.nvcc: command not found于install_graspgen_pip期间

症状grasp 安装阶段找不到 nvcc
原因CUDA toolkit 挂载失败,或CUDA_HOME环境变量未被docker exec继承
修复确认 Phase 2.5 的nvcc --version探针通过;docker run -e CUDA_HOME=...必须设置,使docker exec能继承

Phase 2.5 的容器内探针执行test -x "${CUDA_HOME}/bin/nvcc"与"${CUDA_HOME}/bin/nvcc" --version | head -1,探针失败说明挂载或环境变量传递有问题,应回到 Phase 2 修正,而不是让 setup 带病运行。

16.CUDA_HOME已设置但容器内 nvcc 不可执行

症状环境变量在,但 nvcc 二进制不可执行
原因bind mount 使用了 Docker 未解析的符号链接路径
修复用readlink -f解析真实目录后挂载真实目录(如/usr/local/cuda-12.4),而非/usr/local/cuda软链

Phase 0 对command -v nvcc的结果执行readlink -f并dirname(dirname())上溯两级得到 toolkit 根,或对/usr/local/cuda执行readlink -f;挂载时src与dst使用同一已解析路径(procedure.md)。这保证容器内/usr/local/cuda-${torch_cuda_version}的检测逻辑(见 install_graspgen_pip.sh)能命中真实目录。

17. bind mount/usr覆盖容器/usr

症状挂载后容器内/usr内容异常
原因宿主 nvcc 位于/usr/bin/nvcc(apt 安装),dirname(dirname())上溯得到/usr
修复Phase 0 拒绝系统目录(/、/usr、/usr/local);CUDA toolkit 应安装到/usr/local/cuda-<version>而非 apt 的nvidia-cuda-toolkit

Phase 0 的显式黑名单检查(procedure.md):

if [[ "${HOST_CUDA_HOME}" == "/" || "${HOST_CUDA_HOME}" == "/usr" || "${HOST_CUDA_HOME}" == "/usr/local" ]]; then echo "Host CUDA toolkit path is a system directory ... refusing to bind-mount." HOST_CUDA_HOME="" fi

把整个系统目录 bind 进容器会静默覆盖容器自身/usr,属于比"找不到 nvcc"更危险的故障,因此选择"拒绝挂载 + 优雅跳过 grasp"的保守策略。

排障纪律:从单点修复到验证证据可信

错误分类与报告

无论哪条陷阱被命中,修复后都必须回到 Phase 6 的收尾动作(procedure.md):

docker exec "${CONTAINER}" bash -c ' cat /tmp/setup.status /tmp/setup.time cat /tmp/build.status /tmp/build.time git -C /home/testuser/IB_Robot rev-parse HEAD HEAD^{tree} grep -n -E "ERROR|Error|error" /tmp/setup.log || true grep -n -E "ERROR|Error|error|Failed|failed" /tmp/build.log || true '

报告必须逐条列出 ERROR 行并标注Fatal / Non-fatal,不能只给行数。另需明确声明 source mode:isolated committed snapshot(PR 证据,带完整 commit 与 tree)、local workspace copy(仅本地调试,标注 local-only)或remote clean clone。PR 证据模式下两个平台必须验证 tree 等于VERIFIED_TREE的快照,单纯重写 commit message 不会使结果失效(SKILL.md)。

陷阱的共性规律

把 21 条陷阱横向对比,可以提炼出四条可迁移的工程经验:

  1. 无 TTY 环境先解决"非交互"问题:NOPASSWD:ALL、DEBIAN_FRONTEND=noninteractive、sudo -n true优先,都是为了让脚本在没有终端的容器里可执行(对应陷阱 1、2、4、12)。
  2. 权限以"目标用户实际可写"为准:缓存探针用testuser而非 root 执行,UID/GID 从宿主id -u/id -g动态取得而非硬编码1000:1000(对应陷阱 2、3、4)。
  3. 下载源全部走镜像:apt→Aliyun、ROS→TUNA、pip→华为云,且以环境变量/venv 内pip.conf形式固化在脚本默认值中(对应陷阱 5~10)。
  4. 优雅降级优于硬失败:无 nvcc 时跳过 grasp、无 git-lfs 时移除 LFS hook、gpgcheck 自动禁用,让"环境不完整"也能产出有意义的验证结论(对应陷阱 14~17,openEuler 侧同类策略见 .agents/skills/ibrobot-docker-verify-oee/SKILL.md)。

快速迭代入口

若容器已通过完整 Phase 2 创建,仅需重跑 setup 时,可直接复用容器执行 quick-run 流程(.agents/skills/ibrobot-docker-verify/references/quick-run.md):重新docker cp工作区、清理venv/build/install/log后重跑bash scripts/setup.sh --yes。注意两次运行之间若 ROS 源发生切换,必须重跑 Phase 3.5 的 ROS 预清理(apt-get purge -y 'ros-*'并移除/opt/ros),否则旧源包会被 setup.sh 的 ROS 检测静默复用,使新源安装路径完全未被验证。

结语

IB_Robot 的 Ubuntu Docker 验证陷阱清单是长时间真实运行沉淀的结果:每一条都对应过一次"看似环境问题、实则流程或脚本设计问题"的排障。将本手册与 procedure.md(Phase 0-6 完整命令)、discipline.md(禁止/允许清单)、SKILL.md(变量与变体)配合使用,可以在遇到陌生报错时先在表中定位,再回到源码确认机制,从而把验证从"反复试错"升级为"可预期、可解释、可复现"。

  • 具身智能
  • 机器人
  • 人工智能
  • 大模型
  • 模型推理服务
  • 本地部署
  • 计算机视觉
  • ROS

【免费下载链接】IB_Robot

Save the code of IB-Robot, an AI robot execution framework developed by openEuler Embedded for embodied intelligence scenarios. It includes references to the forked version of tensormsg, references to lerobot fork, code references to the lerobot_ros2:ros2_ws branch, as well as some code related to development usability.

项目地址:https://gitcode.com/openeuler/IB_Robot
点击查看免费下载

相关推荐

上一篇:终极指南:10分钟用vRain制作专业古籍电子书,让传统经典焕发数字新生
下一篇:Swagger UI 验证徽章变红?3 步定位 Schema 校验与错误标记的根因

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询