← 返回课程门户 📚 课程资料中心

运行环境报告

VisualTechLab 实训台 · Jetson Orin Nano
课程门户 / 运行环境报告

VisualTechLab 实训台运行环境报告

6 核ARM Cortex-A78AE
最高 1.73 GHz
1024CUDA 核心
NVIDIA Ampere
8 GBLPDDR5 内存
zram 3.7 GiB
238 GBNVMe SSD
已用 23%
Ubuntu 22.04.5 LTS JetPack 6.x · L4T 5.15-tegra Docker 29.7.1 + NVIDIA Runtime Python 3.10.12
勘察日期 2026-09-08 192.168.31.130 · ld-desktop SSH 只读采集

本报告为实训台实机环境勘察的权威记录:硬件 / 软件 / 业务架构 / 18 实验清单 / 模拟教学环境可行性评估。 供教学备课、课程建设与商务展示使用。云端模拟环境(本门户)即基于本报告方案建设。

勘察日期:2026-09-08
目标主机:192.168.31.130(Jetson Orin Nano 实训台,主机名 ld-desktop)
勘察方式:SSH 只读远程采集,未做任何改动
文档位置:/Users/ido/ido2026/101.Business/Dev/python/VisualTechLab/

一、硬件环境

项目详情
**设备型号**NVIDIA Jetson Orin Nano 超级版开发套件(Engineering Reference Developer Kit Super)
架构aarch64 / ARM64(Tegra 嵌入式平台,非普通 x86 PC)
CPU6 核 ARM Cortex-A78AE,最高 1.73 GHz,最低 115 MHz
GPU集成 NVIDIA Ampere 架构(Orin nvgpu,1024 CUDA 核心),容器内可见 `GPU 0: Orin`
内存7.4 GiB(8 GB 版本),zram 交换分区 3.7 GiB(6 个 zram 设备,各 635 MB)
存储238.5 GB NVMe SSD,根分区 `/` 为 ext4 共 233 GB,已用 51 GB(23%),剩余 171 GB
网络有线网口 `enP8p1s0`,IP `192.168.31.130/24`;WiFi(wlP1p1s0)、CAN 总线存在但未启用;Docker 网桥 `3.7.33.1/24`
系统温度约 52 ℃,当前 1 分钟负载 0.06(基本空闲)
运行时长已开机约 2 小时

外接实训硬件(从软件栈与设备节点推断)

外接实训硬件 · 驱动与接口
📷
Orbbec 深度相机pyorbbecsdk · RGB-D
🎥
大恒 GigE 工业相机Galaxy SDK · gxipy
✋
灵巧手 / 舵机UartAssist · 串口
⚙️
PLC 传送带BeltOperator · TCP
🤖
myCobot 机械臂mycobot_stack
🎙️
Sipeed 语音模块麦克风阵列 · sounddevice
🧩
MyBlockly图形化编程 AppImage

这是一台 AI 机器人视觉实训台,包含以下外接硬件:

硬件驱动/软件设备节点/证据
实训箱本体(AI 一体箱)——箱体尺寸:长 70cm × 宽 55cm × 高 10cm(承载全部外接硬件,统一参数)
奥比中光 Orbbec RGB-D 深度相机pyorbbecsdk、OrbbecViewer`/opt/pyorbbecsdk`、OrbbecSDK 库、容器内 `/dev/dri/renderD128/129`
大恒图像 GigE 工业相机Galaxy SDK、gxipy`/opt/Galaxy_Linux-armhf_*`、`camera.py`(gxipy)、`/opt/device_app/.../train_2dcamera.py`
灵巧手/舵机(串口控制)UartAssist(pyserial)`/opt/uhandclient`、`uart_assist.py`(serial.Serial /dev/ttyUSB*)
传送带(PLC 控制)BeltOperator(PLC 协议)`/opt/plcclient`、`belt_operator.py`(TCP 连接 PLC)
机械臂(myCobot)mycobot_stack + StackAlgorithm`mycobot_stack.py`、`StackAlgorithm.py`
Sipeed 语音模块(麦克风阵列)SipeedMicRecorder`sipeed_assist.py`(sounddevice 音频采集)
图形化编程 MyBlocklymyblockly AppImage`/opt/myblockly-arm64-latest.AppImage`

容器运行时已直通 USB 总线(--device /dev/bus/usb),勘察时可见:

  • /dev/video0、/dev/video1(2 路摄像头)
  • /dev/ttyACM0(USB 串口,灵巧手/PLC 控制器)
  • /dev/dri/card0/1、renderD128/129(GPU/显示渲染节点)

二、软件环境

2.1 宿主机(ld-desktop)

项版本/值
操作系统Ubuntu 22.04.5 LTS(Jammy Jellyfish)
内核5.15.148-tegra(NVIDIA L4T / JetPack 6.x 定制内核)
Python3.10.12(系统自带)
Docker Engine29.7.1(Community),API 1.55,OS/Arch linux/arm64
Docker Composev5.3.1
Docker 存储驱动overlay2,cgroup v2(systemd driver)
Docker 数据目录`/data/docker`(**占 43 GB**,其中镜像 23 GB)
NVIDIA Container Runtime已安装(`nvidia` 是默认 runtime 之一),GPU 容器可用
systemd 服务`device_app.service`(Flask 门户)—— 勘察时 `inactive`,但门户进程 pid 5048/5050 由 run.sh 直接拉起在运行

2.2 宿主机 Python 关键包

Flask                 2.2.5
Flask-SocketIO        5.6.1
python-socketio       5.16.3
docker                7.1.0          # 通过 Docker SDK 启停容器
opencv-contrib-python 4.11.0.86
opencv-python         4.11.0.86
torch                 2.8.0
torchaudio            2.8.0
torchvision           0.23.0
注意:宿主机跑门户和设备演示,不直接跑深度学习推理(推理在容器里)。

2.3 当前运行的实验容器

项值
容器名`jovial_brown`
镜像`39.101.211.60:5000/ld/jetson-orin-nano-gpu:v1`(23.1 GB)
基础镜像`nvcr.io/nvidia/l4t-ml:r36.2.0-py3`(NVIDIA L4T ML)
运行时`nvidia`(GPU 直通),特权模式 true
资源限制CPU 4 核,内存 6 GB
启动入口`/opt/startup.sh`
默认启动命令`nvidia-smi`(仅用来保活)
当前实验`voicecommand`(语音指令)
当前用户`user1`

容器内环境:

项版本
OSUbuntu 22.04.5 LTS(中文 locale zh_CN.utf8)
Python3.10.12
CUDA12.2(nvcc V12.2.140)
torch2.1.0
torchvision0.16.0+fbb4cc5
torchaudio2.1.0+6ea1133
tensorflow2.14.0+nv23.11(NVIDIA 版)
onnxruntime-gpu1.16.3
onnx1.16.0
opencv-contrib-python4.11.0.86
numpy1.26.0
scipy1.15.3
matplotlib3.10.9
Flask2.2.5
pyserial3.5
pyzbar0.1.9
pillow12.3.0
JupyterLab3.6.6(中文语言包 4.5.post3)

容器内服务端口映射(宿主机→容器):

服务宿主机端口容器端口URL / 用途
SSH3277222root 登录(密码 `123456`)
VNC(TigerVNC)327735901远程桌面(密码 `123456`)
noVNC(网页桌面)327746901`http://192.168.31.130:32774/vnc.html?autoconnect=true&...password=123456`
JupyterLab327758888`http://192.168.31.130:32775/lab`(无 token,allow-root)

容器挂载:

宿主机路径容器路径用途
`/dev/bus/usb``/dev/bus/usb`USB 设备直通(摄像头/串口/语音模块)
`/data/docker4bd/private/user1``/data/personal`用户工作目录(notebook_dir,rw)

2.4 本地镜像列表

仓库TagImage ID大小备注
`39.101.211.60:5000/ld/jetson-orin-nano-gpu`v111e6ca36291f23.1 GB**当前在使用**
`jetson-orin-nano-gpu`v111e6ca36291f23.1 GB同镜像的本地标签
`jetson-gpu`novnc522f9126d91c23 GB旧版(5 周前)
`jetson-gpu`vncde51e4ff5acb20.4 GB旧版(5 周前)
`nvcr.io/nvidia/l4t-ml`r36.2.0-py3997c78d663fc18.9 GBNVIDIA 官方基础镜像(2 年前)

Docker 资源占用:镜像 23.1 GB、容器 61 MB、无命名卷、无 Build Cache。

三、业务架构

3.1 整体架构图

系统运行架构
🖥️
学生浏览器Chrome · http://192.168.31.130:8080 · noVNC / JupyterLab
:8080 · Flask 门户(web.py + SocketIO)
🔐
宿主机门户 /opt/device_app登录(user1/user2)→ 选实验 → 一键启动容器(Docker SDK)
32772~32775 端口转发 · nvidia runtime
🐳
实验容器(L4T-ML r36.2.0)中文桌面 Xtigervnc + JupyterLab 3.6 · CUDA 12.2 · CPU 4 核 / 内存 6 GB
USB / 串口 / Dri 直通(--device /dev/bus/usb)
🔧
实训硬件Orbbec 深度相机 · 大恒工业相机 · 灵巧手 · PLC 传送带 · myCobot 机械臂 · Sipeed 语音模块
学生浏览器(Chrome)
    │  http://192.168.31.130:8080  ← Flask 门户首页 /login
    ▼
┌────────────────────────────────────────────────────────────┐
│  宿主机门户:/opt/device_app/web.py (Flask + SocketIO)   │
│  监听 0.0.0.0:8080,root 运行                              │
│  账号:user1 / user2,密码均为 123456(见 config.py)      │
│                                                             │
│  登录后 → 选实验 → 点"启动实验" → SocketIO 异步:          │
│    1) 停掉当前用户正在跑的容器(stop_all_containers)      │
│    2) 拷贝实验模板:/opt/device_data/<实验>/                │
│              → /data/docker4bd/private/<user>/<实验>/      │
│    3) docker run 新容器:                                  │
│       - nvidia runtime, privileged, --device /dev/bus/usb  │
│       - 内存 6G,CPU 4 核                                   │
│       - 环境变量 EXPERIMENT_LD, USERNAME_LD, VNC_PASSWORD  │
│    4) 返回 noVNC URL + JupyterLab URL 给前端               │
│                                                             │
│  状态文件:/opt/device_data/<user>_docker.txt(JSON)       │
│  容器编排配置:/opt/device_app/docker_supervise/config/     │
│                default.xml                                  │
└────────────────────────────────────────────────────────────┘
    │  32772~32775 端口转发
    ▼
┌────────────────────────────────────────────────────────────┐
│  实验容器(每学生/每实验一个,同时只跑一个)                │
│  - 中文桌面(Xtigervnc + noVNC)                           │
│  - JupyterLab 3.6(/data/personal 为工作目录)             │
│  - SSHD(root/123456)                                     │
│  - Python 3.10 + CUDA 12.2 + 全套 AI 库                   │
│  - 学生通过浏览器 noVNC 桌面或 JupyterLab 做实验           │
└────────────────────────────────────────────────────────────┘
    │  USB/串口/Dri 直通
    ▼
实训硬件(相机/灵巧手/PLC/传送带/机械臂/语音模块)

3.2 宿主机目录结构

/opt/
├── device_app/         211 MB   ← Flask 门户(主程序 web.py,20 KB)
│   ├── web.py                   Flask 路由与容器编排逻辑
│   ├── config.py                账号、镜像地址、模式(offline/online)
│   ├── run.sh                   启动脚本(PYTHONPATH 注入)
│   ├── device_app.service       systemd 单元
│   ├── docker_supervise/        Docker SDK 封装(common / sections / config)
│   │   └── config/default.xml   容器创建参数模板(端口、挂载、镜像)
│   ├── projects/                早期 12 个实验模板(与 device_data 重复)
│   ├── static/ templates/       门户前端
│   ├── toolsutil.py             工具函数
│   └── desktop.png              桌面快捷方式图标
│
├── device_data/        203 MB   ← 18 个实验模板库(当前版本)
│   ├── <实验目录>/               每个实验 = PDF + main_ui.py + .ipynb + 辅助模块
│   ├── resource/                 公共资源(images/、json/)
│   └── user1_docker.txt          当前 user1 的容器状态 JSON
│
├── device_demo/         45 MB   ← 设备演示 Web(web.py 44 KB)
│   ├── web.py                    直接操控传送带/相机/色块/机械臂/语音训练
│   ├── belt_operator.py          PLC 传送带控制
│   ├── camera.py                 大恒相机封装(gxipy)
│   ├── color_block.py            色块识别
│   ├── uart_assist.py            串口舵机/灵巧手控制
│   └── ...(train_*.py 训练脚本等)
│
├── pyorbbecsdk/                 ← 奥比中光深度相机 SDK(Python 绑定)
├── uhandclient/                 ← 灵巧手客户端
├── plcclient/                   ← PLC 客户端
├── Galaxy_Linux-*/              ← 大恒工业相机 GigE SDK
├── OrbbecViewer_*/              ← 奥比中光 Viewer 工具
├── yolov/ voice_model/          ← YOLOv、语音模型
├── desktopMonitor/              ← 桌面监控程序
├── installfile/                 ← 系统安装文件
├── nvidia/                      ← NVIDIA JetPack/L4T 相关
└── myblockly-*.AppImage          ← 图形化编程

/data/
├── docker/            43 GB     ← Docker 数据根目录(镜像、容器层)
├── docker4bd/        764 KB     ← 实验工作区(宿主机侧)
│   ├── public/                  公共资源挂载点(空)
│   ├── project/                 项目挂载点(空)
│   └── private/
│       └── user1/
│           └── voicecommand/    ← 语音指令实验(当前运行中,含 PDF + main_ui.py + voice.wav)
└── tee/                         ← TEE 安全目录

3.3 Flask 门户路由清单(web.py)

路由方法功能
`/login`GET登录页
`/login_user`GET/POST登录验证(user1/user2,密码 123456)
`/`GET主界面(实验列表)
`/viewer`GETPDF 课件预览
`/pdfjs/<path>`GETPDF.js 静态资源
`/start_docker`POST/GET**启动实验容器**(核心逻辑)
`/stop_docker`POST/GET停止实验容器
`/container_list`POST/GET查询容器列表
`/container_status`POST/GET查询容器运行状态(noVNC/JupyterLab URL)
`/image_list`POST/GET查询镜像列表
`/upload_file`POST上传文件到实验目录
`/logout`GET登出
`/start_install`POST/GET安装/拉取镜像(在线模式)
`/images/<path>`GET镜像相关静态资源

启动参数从 config.py + docker_supervise/config/default.xml 合并而来。

3.4 外呼依赖连通性

目标用途勘察时状态
`39.101.211.60:5000`私有 Harbor 镜像仓库❌ **不可达**(HTTP 000,可能已关机/不在网络)
`192.168.31.10`apiServer + fileServer(教案/文件)❌ **不可达**

当前 config.py 配置 mode_type = "offline",所以外呼失败不影响使用(镜像已本地存在,课件已在 device_data 中)。

四、实验清单:共 18 个实验

每个实验目录位于 /opt/device_data//,结构统一:

<实验名>/
├── <hash>.pdf              实验指导书(PDF,10-20MB)
├── main_ui.py              实验主程序(Tkinter 桌面 UI)
├── *.ipynb                 Jupyter Notebook(教学讲解)
├── *_assist.py             硬件辅助模块(串口/相机/语音)
├── tool_util.py / tools_util.py  工具函数
├── images/ Log/            图片素材/日志
└── requriment.txt          依赖声明(拼写错误,原作者笔误)

4.1 按主题分类

18 个实验 · 主题分布
工业识别
5
手部 AI
4
语音 AI
3
人脸 AI
3
姿态检测
1
相机标定
1
机器人
1
分类目录名中文名体积
**视觉-AI 人脸**facedetector02人脸检测17 MB
facialcontourdetection03面部轮廓检测17 MB
facialdepth06面部深度检测(深度相机)17 MB
**视觉-AI 手部**handdetector01手部检测8.3 MB
handrecognition13手势识别8.5 MB
fingerguessing15猜拳游戏17 MB
doublehandaddition14双手加法(手势算数)8.2 MB
**视觉-AI 姿态/人体**posedetector04姿态检测17 MB
**视觉-AI 工业识别**workpiecerecognize10工件识别5.8 MB
intelligentsorting11智能分拣(含机械臂)1.7 MB
barcoderecognition07条形码识别19 MB
qrcoderecognition08二维码识别19 MB
carnumberrecognition09车牌识别19 MB
**视觉-相机标定**camerafocallength05相机焦距标定17 MB
**语音-AI**voicecommand18语音指令控制(灵巧手)720 KB
speechrecognition16语音识别828 KB
voiceenglishtranslation17语音英语翻译664 KB
**机器人**robotstack12机器人码垛1.1 MB
**公共资源**resourceimages/、json/(被各实验引用)13 MB

共 18 个有效实验 + 1 个公共资源目录,合计 约 203 MB。

4.2 视觉类实验普遍偏大的原因

  • 每个都捆绑一份 PDF 实验指导书(8-18 MB)
  • 多数含 .ipynb notebook 讲解
  • 部分含预训练模型/样例图片(如 facedetector 的 Orbbec SDK 二进制是原作者误放)

4.3 硬件抽象层(HAL)现状

原作者已把硬件调用封装成独立的 Python 类,业务逻辑不直接碰底层——这是后续做模拟(Mock)教学环境的有利条件:

硬件封装类主要接口
灵巧手/舵机(串口)`UartAssist``open_serial()`、`control_mult_servo_move(t, angles)`、`control_full_action_stop()`、`reset_hand()`、`close_serial()`
传送带(PLC)`BeltOperator``open_connect()`、`start_run()`、`stop_run()`、`write_speed(v)`、`read_speed()`、`write_direction(d)`、`read_status()`
大恒工业相机`Camera(gxipy)``open_cam_device()`、`start_acquisition()`、`getImg()`、`close_cam_device()`
深度相机`orbbec_camera_*.py` + pyorbbecsdk获取 RGB + 深度帧
语音麦克风`SipeedMicRecorder``init_device()`、`start_record(fname)`、`stop_record()`、`is_recording()`
机械臂码垛`mycobot_stack` + `StackAlgorithm`位姿/抓取指令/码垛坐标计算
注:uart_assist.py 和 tools_util.py 在多个实验目录下各有一份副本(代码有细微差别),不是单例共享模块。

五、默认账号与密码(⚠️ 教学默认值,勿暴露公网)

服务账号密码
门户(web.py:8080)user1 / user2`123456`
容器 SSH(32772)root`123456`
VNC(5901)—`123456`
noVNC(6901)—`123456`
JupyterLab(8888)(allow-root,无 token)—
Harbor(default.xml)admin`LD_harbor_210720`(仓库不可达)

六、监听端口一览

端口进程用途
22sshd宿主机 SSH
53systemd-resolved本地 DNS
111rpcbindRPC 端口映射
631cupsd打印服务
**8080**python (web.py)**Flask 实验门户**
32772docker-proxy容器 SSH
32773docker-proxy容器 VNC
32774docker-proxy容器 noVNC 网页桌面
32775docker-proxy容器 JupyterLab
13486dockerdDocker 远程 API(tcp://192.168.31.130:13486,供 docker_supervise 调用)

七、可行性评估:拉到本地 & 模拟教学环境

7.1 各部分内容的可迁移性

内容位置体积能否拉到 Mac/普通 Ubuntu能否在非 Jetson 机器上运行
门户代码 device_app`/opt/device_app`211 MB✅ rsync 直接拉✅ 纯 Flask,可直接运行(需改 Docker SDK 调用)
18 个实验课件+代码`/opt/device_data`203 MB✅ rsync 直接拉✅ Notebook/PDF 可阅读;纯 CPU 算法代码可跑;Orbbec/gxipy 等 aarch64 二进制装不上
设备演示系统`/opt/device_demo`45 MB✅ rsync 直接拉❌ 直接依赖实训台硬件
**Docker 实验镜像**`/data/docker`**23.1 GB**✅ 可 `docker save` 离线搬运❌ **无法在 Mac/普通 x86 PC 运行**:镜像基于 NVIDIA L4T/Tegra,CUDA 绑定 Jetson GPU;即使是 M 芯片 Mac(同为 arm64)也没有 N 卡,容器内 GPU 推理全废
学生作业数据`/data/docker4bd/private/`<1 MB✅ 直接拉—

7.2 核心结论

1. 纯文档/代码级别复刻(460 MB):rsync 几分钟完成,适合备课、改课件、离线阅读 notebook。

2. 完整 GPU 实验环境:只能在另一台 Jetson 设备(Orin/Xavier/Nano,JetPack 6.x + nvidia-container-toolkit)上还原;Mac/x86 Ubuntu 都跑不了那个 23 GB 镜像。

3. 模拟教学环境(Hardware-in-the-Loop Mock):完全可行,且代码结构支持——只需在硬件抽象层之上加一套 Mock 驱动实现,让学生发"传送带启动/手势张开"等指令时,Mock 返回预设状态和数据。

八、模拟教学环境建设方案(讨论方向)

8.1 为什么可行

原作者已将所有硬件调用封装在独立驱动类(UartAssist、BeltOperator、Camera、SipeedMicRecorder、mycobot_stack)中,业务代码(实验 main_ui.py、notebook、AI 识别)通过这些类的方法签名间接访问硬件。这意味着:

按相同类名、相同方法签名实现一套"假驱动",业务代码一行不改即可在普通 Ubuntu 上运行;由配置开关切换 real / mock 模式。

8.2 三层模拟深度

层级描述教学价值工作量
**L1 接口级 Mock**方法调用返回预设状态/ACK;状态机维护内部变量(speed、direction、servo angles)验证指令链路、协议、状态机逻辑小
**L2 数据级回放**Mock 相机不生成假图,而是**回放现场已录的真实图片/视频/音频**(device_data 内已有 voice.wav、images/ 等素材);识别算法(OpenCV/ONNX/Whisper)跑真模型,输出真结果算法实验可完整运行(人脸/手势/条码/车牌),学生看到真识别框中
**L3 数字孪生可视化**Web 页面 2D/3D 展示传送带转动、色块移动、机械臂动作、相机视野;与 L1/L2 联动演示效果好,替代 noVNC 桌面的"看设备动"诉求较大

8.3 推荐路线

1. 第一步:拉代码 —— rsync 把 /opt/device_app、/opt/device_data、/opt/device_demo(共 ~460 MB)同步到本地 VisualTechLab/ 目录

2. 第二步:单实验打样 —— 建议选 voicecommand(最简单,验证架构)或 intelligentsorting(传送带+相机+机械臂全链路,最能暴露问题)

3. 第三步:抽出 HAL 层 —— 建 hal/real/ 与 hal/mock/ 两套实现,一个全局 SIMULATION_MODE 开关

4. 第四步:逐个实验适配 —— 18 个实验复用同一套 HAL,打样完成后其余实验适配成本快速下降

5. 第五步(可选):数字孪生可视化 + 故障注入(模拟丢包/设备离线/识别失败)

8.4 模拟覆盖度估算

模拟教学覆盖率 · 约 75~80%
可完整模拟 13~14 个(语音 3 + 视觉识别 8~10 + 条码/二维码/车牌) 可部分模拟 4 个(双手加法/猜拳/分拣/码垛) 需真机 2~3 个(焦距标定/深度测量/机械臂公差)
  • 可完整模拟(无需硬件):语音类 3 个、视觉识别类 8-10 个(用回数据/预置模型)、条码/二维码/车牌识别 —— 约 13-14 个实验
  • 可部分模拟(算法可跑,但硬件交互需简化):双手加法、猜拳、智能分拣、机器人码垛 —— 约 4 个
  • 无法纯软件模拟(必须真机):相机焦距标定、深度测量、机械臂碰撞/公差、硬件接线故障排查 —— 约 2-3 个

总体模拟覆盖率约 75-80%,足以支撑课前预习、课下复习、算法反复练习、批量学生无设备自学等场景。

8.5 模拟环境不需要 23GB Jetson 镜像

在普通 Ubuntu(x86_64 或 arm64 Mac)上所需的只是:

  • Python 3.10
  • CPU 版 torch / onnxruntime / opencv-python / flask / flask-socketio / pyserial / pyzbar / faster-whisper
  • 课件代码(~460 MB)
  • 预置模型 + 回放素材(按需下载)

总磁盘占用预计 < 3 GB(不含模型)。

九、建议的后续动作(待讨论确认)

  • [ ] 用 rsync 把 /opt/device_app、/opt/device_data、/opt/device_demo 同步到本地 VisualTechLab/remote/
  • [ ] 选定第一个 Mock 打样实验(voicecommand 或 intelligentsorting)
  • [ ] 在本地 VisualTechLab/simulator/ 搭建 HAL 框架,接入 Mock 实现
  • [ ] 跑通第一个闭环实验后,批量适配其余实验
  • [ ] (可选)数字孪生可视化页面
  • [ ] (可选)镜像离线备份:docker save 出 23GB 镜像归档存移动硬盘,以防设备故障

附录:勘察时使用的非侵入式命令(仅读)

# 连通性
ping 192.168.31.130
nc -zv 192.168.31.130 22

# 硬件/系统
lscpu; free -h; df -hT; lsblk; ip -brief addr; dmidecode -s system-product-name

# Docker
docker ps -a; docker images; docker volume ls; docker network ls; docker system df;
docker inspect jovial_brown; docker exec jovial_brown bash -c '...'

# 业务目录
ls -la /opt/device_app; ls -la /opt/device_data; ls -la /data/docker4bd;
grep -n "@app.route" /opt/device_app/web.py; ss -tlnp

所有采集均通过 SSH 以只读查询为主,未在对端写入或修改任何文件(除之前按你指示配置了 dev 账号的 SSH 公钥与 sudo NOPASSWD)。

十、二次验证补充信息(Workbody P0验证)

以下信息来自 Workbody 自动化探测脚本的二次验证,对首次勘察结果进行补充确认。

10.1 Docker 远程 API 可达性

  • Docker daemon 监听 tcp://192.168.31.130:13486(首次勘察已记录)
  • P0 验证确认:从远端 Python 容器通过 TCP 访问该端口可成功调用 Docker API(list_containers、list_images 等接口均正常返回)
  • 这意味着 liveservice 容器有两种方式管理宿主机 Docker:
  1. 挂载 /var/run/docker.sock(推荐,更安全、不暴露 TCP 端口)
  2. 通过 TCP 连接 192.168.31.130:13486(已验证可行,但需确保端口仅内网访问)

10.2 容器内 Docker sock 访问

  • P0 验证确认:容器内挂载 /var/run/docker.sock 后,可正常调用 Docker SDK 管理宿主机容器,包括:
  1. 启动 / 停止实验容器
  2. 查询容器状态
  3. 获取容器日志
  4. 动态端口映射
  • 验证方式:在 Python 测试容器内安装 docker 包,挂载 sock 后成功 list / containers / create / start

10.3 离线环境确认

  • 服务器无法访问外部网络:39.101.211.60:5000(私有 Harbor 仓库)不可达;192.168.31.10(教案 / 文件服务器)不可达;公网不通(无 Internet 连接)
  • 部署影响:不能依赖 docker pull 或 apt install 从外网获取资源,必须采用"本地 build → docker save → scp 传输 → docker load"的离线部署流程
  • 好消息:实验镜像 jetson-orin-nano-gpu:v1(23GB)已在本地,PostgreSQL 镜像可以在本地 Mac(arm64)pull 后一起打包传输

10.4 磁盘资源余量确认

  • 根分区 233GB,已用 51GB(23%),剩余 171GB 可用
  • Docker 数据目录 /data/docker 占 43GB(镜像 23GB + 容器层)
  • 新增 PostgreSQL 数据预计占用 < 1GB;新增 liveservice 镜像预计 < 500MB;学生数据(代码 + 成绩 + 日志)预计一学期 < 5GB
  • 磁盘余量充足,无需额外扩容

10.5 Python 与 pip 环境

  • 宿主机 Python 3.10.12,pip 可用;但离线环境下 pip install 无法从 PyPI 下载包
  • 进一步确认全 Docker 化部署的必要性:所有 Python 依赖打包进 Docker 镜像,不需要在宿主机 pip install
  • 本地 Mac(arm64)build 镜像 → 传输到 Jetson → 直接运行,零依赖

10.6 原厂容器参数模板确认

  • /opt/device_app/docker_supervise/config/default.xml 包含完整的容器创建参数:镜像名、runtime、CPU/内存限制、端口映射范围、设备直通、环境变量、工作目录挂载
  • 该模板可被 liveservice 直接读取或复刻,确保容器启动参数与原厂完全一致
  • 原厂容器启动逻辑位于 /opt/device_app/web.py 的 start_docker 路由函数中

10.7 systemd 服务状态补充

  • device_app.service systemd 单元文件存在,但勘察时服务状态为 inactive
  • 实际的 Flask 门户进程(pid 5048/5050)由 /opt/device_app/run.sh 直接拉起,未通过 systemd 管理
  • 部署影响:liveservice 部署时需要决定如何处理原厂 web.py 进程(停掉并由 liveservice 替代,或改端口共存)
内容同步自 docs/01-环境勘察报告.md(最后编辑 2026-09-08 20:34 · 含 Workbody P0 二次验证补充)