在 Docker 中运行 Isaac Lab#
Docker 将 Isaac Lab 及其依赖打包为可复用环境。 docker/container.py 是在容器中运行 Isaac Lab 的主要入口。它封装 docker compose ,无需记住哪些 Dockerfile、环境文件和卷挂载应搭配使用;只需指定一种 配置,脚本会组装其余内容。
构建的镜像也是其他工作流的基础: 在 HPC 集群上运行 将其转换为 Apptainer 镜像, 云部署 配置运行它的机器。
小心
标准 Isaac Lab 容器依赖 Isaac Sim Docker 镜像。运行该容器即表示默认同意 NVIDIA 软件许可协议 。如果不同意 EULA,请勿运行。 kitless 镜像不包含 Isaac Sim 或 Kit。
先决条件#
安装 Docker Engine 、 Docker Compose 和 NVIDIA Container Toolkit 。容器已使用 Docker Engine 26.0.0 和 Docker Compose 2.25.0 测试,请使用这些或更新版本。完成 安装后步骤 ,使 Docker 无需 sudo 即可运行。
Isaac Sim 的 容器安装 文档更详细地介绍了同样的前置要求,包括如何获得 Isaac Sim 镜像访问权限。
备注
由于对 snap 的限制,请确保 Isaac Lab 目录位于 /home 目录树下使用 docker 时。
容器配置#
这里的配置是 Docker Compose profile : docker-compose.yaml 为每个服务标记一种 profile,Compose 只启动已启用 profile 对应的服务。因此,指定配置名会选择配套的一组内容:一个服务、一个 Dockerfile、一组环境文件和一个镜像名。
区域配置 |
Compose 服务 |
Dockerfile |
环境文件 |
基础镜像 |
|---|---|---|---|---|
|
|
|
|
Isaac Sim 镜像 |
|
|
|
|
先构建的 |
|
|
|
|
独立镜像,不依赖 Isaac Sim |
下文各命令的第一个位置参数是配置名,默认为 base 。一次只应用一种配置,生成镜像与容器均名为 isaac-lab-<profile> 。如果希望并行保留同一配置的多个变体,传入 --suffix 添加名称后缀。集群部署的导出命令要求无后缀镜像名,因此不要使用 --suffix 。
各镜像的实际内容及选择方式见 容器镜像 。
启动、运行与取回结果#
在宿主机仓库根目录构建并启动默认 base 容器,再打开其中的 shell。要使用其他镜像,追加配置名:
./docker/container.py start
./docker/container.py enter
在容器中,不使用可视化器运行日志示例:
uv run isaaclab -p scripts/tutorials/00_sim/log_time.py --viz none
脚本将每步仿真时间写入 /workspace/isaaclab/logs/docker_tutorial/log.txt 。按 Ctrl+C 停止脚本,输入 exit 返回宿主机 shell。停止容器前取回结果:
./docker/container.py copy
./docker/container.py stop
日志现位于宿主机的 docker/artifacts/logs/docker_tutorial/log.txt 。 stop 命令删除容器及其 Compose 管理的卷,包括日志和缓存,因此应先复制所需内容。镜像会保留;停止后如需删除,运行 docker image rm isaac-lab-base ,下次 start 会重新构建。其他清理方式见 Docker 清理 。
log_time.py 的代码
1# Copyright (c) 2022-2026, The Isaac Lab Project Developers (https://github.com/isaac-sim/IsaacLab/blob/main/CONTRIBUTORS.md).
2# All rights reserved.
3#
4# SPDX-License-Identifier: BSD-3-Clause
5
6"""
7This script demonstrates how to generate log outputs while the simulation plays.
8It accompanies the tutorial on docker usage.
9
10.. code-block:: bash
11
12 # Usage
13 uv run python scripts/tutorials/00_sim/log_time.py
14
15"""
16
17"""Parse the command-line arguments first."""
18
19
20import argparse
21import os
22
23from isaaclab.app import add_launcher_args, launch_simulation
24
25# create argparser
26parser = argparse.ArgumentParser(description="Tutorial on creating logs from within the docker container.")
27# append simulation launcher cli args
28add_launcher_args(parser)
29# parse the arguments
30args_cli = parser.parse_args()
31
32"""Rest everything follows."""
33
34from isaaclab.sim import SimulationCfg, SimulationContext
35
36
37def main():
38 """Main function."""
39 # Specify that the logs must be in logs/docker_tutorial
40 log_dir_path = os.path.join("logs")
41 if not os.path.isdir(log_dir_path):
42 os.mkdir(log_dir_path)
43 # In the container, the absolute path will be
44 # /workspace/isaaclab/logs/docker_tutorial, because
45 # all Python execution is done through the uv-managed workspace
46 # and the calling process' path will be /workspace/isaaclab
47 log_dir_path = os.path.abspath(os.path.join(log_dir_path, "docker_tutorial"))
48 if not os.path.isdir(log_dir_path):
49 os.mkdir(log_dir_path)
50 print(f"[INFO] Logging experiment to directory: {log_dir_path}")
51
52 # Configure the simulation
53 sim_cfg = SimulationCfg(dt=0.01, device=args_cli.device)
54 # Launch the simulator runtime that the configuration needs
55 with launch_simulation(sim_cfg, args_cli):
56 # Initialize the simulation context
57 sim = SimulationContext(sim_cfg)
58 # Set main camera
59 sim.set_camera_view([2.5, 2.5, 2.5], [0.0, 0.0, 0.0])
60
61 # Play the simulator
62 sim.reset()
63 # Now we are ready!
64 print("[INFO]: Setup complete...")
65
66 # Prepare to count sim_time
67 sim_dt = sim.get_physics_dt()
68 sim_time = 0.0
69
70 # Open logging file
71 with open(os.path.join(log_dir_path, "log.txt"), "w") as log_file:
72 # Simulate physics
73 while sim.is_running():
74 log_file.write(f"{sim_time}" + "\n")
75 # perform step
76 sim.step()
77 sim_time += sim_dt
78
79
80if __name__ == "__main__":
81 # run the main function
82 main()
备注
镜像在构建时将仓库复制到 /workspace/isaaclab ,因此不会自动包含构建后的修改。为加快开发迭代,Compose 文件从宿主机绑定挂载 source 、 scripts 、 docs 和 tools ,这些目录的修改会立即出现在容器内。其他内容需要重新构建。
container.py 命令参考#
运行 ./docker/container.py --help 列出命令,运行 ./docker/container.py <command> --help 查看对应参数。
命令 |
描述 |
|---|---|
|
构建镜像,不创建容器。 |
|
构建镜像,并在后台启动容器。 |
|
在运行中的容器内打开 Bash shell。 |
|
打印合并后的 Compose 配置;使用 |
|
将日志、数据和构建的文档复制到宿主机 |
|
停止并删除容器及其 Compose 管理的卷。 |
各命令均接受以下参数:
参数 |
描述 |
|---|---|
|
可选配置名,默认为 |
|
按给定顺序,在 |
|
按给定顺序,在配置默认值之后合并额外环境文件。 |
|
向镜像与容器名称追加 |
|
打印解析后的容器接口配置,不执行命令。 |
|
显示帮助并退出。 |
扩展 Compose 配置#
备注
以下 CloudXR 独立配套容器示例沿用 Isaac Lab 2.x 工作流。Isaac Lab 3.0 遥操作应使用 配置 Isaac Capture 与 CloudXR 中的单容器配置,由它自动启动 CloudXR。当前遥操作工作流不要使用旧的 Compose 补丁。
--files 和 --env-files 将额外 Compose 文件和环境文件合并到生成配置,无需编辑版本控制中的文件,即可叠加可选组件。向 XR 设备串流的示例会在 base 旁添加 CloudXR Runtime 服务:
./docker/container.py start --files docker-compose.cloudxr-runtime.patch.yaml --env-files .env.cloudxr-runtime
停止时使用同样参数。遥操作设置、防火墙规则和客户端连接步骤见 配置 Isaac Capture 与 CloudXR 。组合行为不符合预期时,用 ./docker/container.py config 打印合并结果。
运行之间保留的内容#
Compose 文件为 Isaac Sim 缓存、日志和用户数据声明命名卷。复用容器时,这些卷保持可用;但 container.py stop 会运行 docker compose down --volumes 并删除它们。先运行 container.py copy ,再运行 stop ,以将结果保存到宿主机。
container.py copy 将最常需要的三个卷——logs 、 data_storage 和 docs/_build——提取到宿主机 docker/artifacts 。其他内容使用 docker cp ,例如 docker cp isaac-lab-base:/workspace/isaaclab/logs . 。
如果从以 root 运行的旧 Isaac Lab 镜像升级,现有卷仍包含 root 所有的文件,当前 uid/gid 1000 运行时用户无法写入。先复制需要保留的内容,再从 docker 目录重新创建卷:
docker compose --file docker-compose.yaml --profile base --env-file .env.base down --volumes
全部命名卷及其容器路径
卷名 |
描述 |
容器路径 |
|---|---|---|
isaac-cache-kit |
存储缓存的 Kit 资源 |
/isaac-sim/kit/cache |
isaac-data-kit |
存储 Kit 数据 |
/isaac-sim/kit/data |
isaac-cache-ov |
存储缓存的 OV 资源 |
/root/.cache/ov |
isaac-cache-pip |
存储缓存的 pip 资源 |
/root/.cache/pip |
isaac-cache-gl |
存储缓存的 GLCache 资源 |
/root/.cache/nvidia/GLCache |
isaac-cache-compute |
存储缓存的计算资源 |
/root/.nv/ComputeCache |
isaac-cache-uv |
存储 kitless 配置的 uv 下载缓存 |
/home/isaaclab/.cache/uv |
isaac-cache-warp |
存储 kitless 配置的 Warp 核函数缓存 |
/home/isaaclab/.cache/warp |
isaac-logs |
存储由 Omniverse 生成的日志 |
/root/.nvidia-omniverse/logs |
isaac-carb-logs |
存储由 carb 生成的日志 |
/isaac-sim/kit/logs/Kit/Isaac-Sim |
isaac-data |
存储由 Omniverse 生成的数据 |
/root/.local/share/ov/data |
isaac-docs |
存储由 Omniverse 生成的文档 |
/root/Documents |
isaac-lab-docs |
存储 Isaac Lab 的文档,当在容器内构建时 |
/workspace/isaaclab/docs/_build |
isaac-lab-logs |
存储由 Isaac Lab 工作流生成的日志,当它们在容器内运行时 |
/workspace/isaaclab/logs |
isaac-lab-data |
存储用户可能希望在容器运行之间保留的所有数据 |
/workspace/isaaclab/data_storage |
在宿主机运行 docker volume ls ,查找带有 Compose 项目前缀的实际名称,再用 docker volume inspect <volume-name> 查看。 kitless 配置使用 uv 和 Warp 缓存,并与其他配置共享文档、日志和数据卷。
通过 X11 转发显示#
X11 转发使容器内启动的图形应用显示在宿主机上。首次 start 会询问是否启用,并将答案记录在 docker/.container.cfg 。以后如需修改,将该文件的 X11_FORWARDING_ENABLED 设为 0 或 1 ,再运行 start ;修改在重新构建时生效。