在 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

环境文件

基础镜像

base

isaac-lab-base

Dockerfile.base

.env.base

Isaac Sim 镜像

ros2

isaac-lab-ros2

Dockerfile.ros2

.env.base + .env.ros2

先构建的 base 镜像

kitless

isaac-lab-kitless

Dockerfile.kitless

.env.kitless

独立镜像,不依赖 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 查看对应参数。

命令

描述

build

构建镜像,不创建容器。

start

构建镜像,并在后台启动容器。

enter

在运行中的容器内打开 Bash shell。

config

打印合并后的 Compose 配置;使用 --output-yaml <path> 可改为写入文件。

copy

将日志、数据和构建的文档复制到宿主机 docker/artifacts 。

stop

停止并删除容器及其 Compose 管理的卷。

各命令均接受以下参数:

参数

描述

profile

可选配置名,默认为 base ;其他配置为 ros2 和 kitless 。

--files [FILE ...]

按给定顺序,在 docker-compose.yaml 之后合并额外 Compose YAML 文件。

--env-files [FILE ...]

按给定顺序,在配置默认值之后合并额外环境文件。

--suffix [SUFFIX]

向镜像与容器名称追加 -SUFFIX ;省略时无后缀。

--info

打印解析后的容器接口配置,不执行命令。

-h, --help

显示帮助并退出。

扩展 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 ;修改在重新构建时生效。