> This page is for version Release 3.0 (default).
> For other versions, use one of these documentation indexes:
> - Release 3.0 (default): https://docs.nvidia.com/isaaclab/3.0/llms.txt
> - Release 2.3: https://docs.nvidia.com/isaaclab/2.3/llms.txt
> - Release 2.2: https://docs.nvidia.com/isaaclab/2.2/llms.txt
> - Release 2.1: https://docs.nvidia.com/isaaclab/2.1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/isaaclab/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/isaaclab/_mcp/server.

# Container images

Each [profile](/source/workflows/docker/index) builds a different image. They differ in what simulation and
rendering stack they carry, which decides how large they are and what they can run. This page
describes the images themselves; to build or run one, name its profile in the
[container lifecycle](/source/workflows/docker/index).

## Choosing an image

| Profile   | Contains                                                                                  | Use it when                                                                                        |
| --------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `base`    | Isaac Lab on the NVIDIA Isaac Sim image, with Kit and RTX rendering                       | You want the default environment, GUI rendering, or anything that needs Isaac Sim                  |
| `ros2`    | The `base` image plus ROS 2 Humble                                                        | You are bridging Isaac Lab to ROS 2 nodes                                                          |
| `kitless` | Ubuntu 24.04, Python 3.12, Newton and OVPhysX physics, OVRTX rendering, four RL libraries | You are training with Newton and want the smallest image; also the only one with no Isaac Sim EULA |

## Building an image

Every image builds with the same command; only the profile name changes. From the repository root,
build the image for a profile from the table above, for example `kitless`:

```bash
./docker/container.py build kitless
```

`./docker/container.py start kitless` also builds the image before starting the container. Without
Compose, build the profile's Dockerfile directly; it uses the same default paths:

```bash
docker build --pull --file docker/Dockerfile.kitless --tag isaac-lab-kitless .
```

Release images are also published pre-built, so building is optional; see [Pre-built image from NGC](/source/workflows/docker/images#pre-built-image-from-ngc).

## Base image

`Dockerfile.base` overlays Isaac Lab's dependencies onto the Isaac Sim container, so it inherits
Kit, RTX rendering, and the Isaac Sim asset pipeline. The Isaac Sim version it builds against is set
by `ISAACSIM_VERSION` in `.env.base`; the other variables in that file control paths inside the
container.

## ROS 2 image

`Dockerfile.ros2` installs ROS 2 Humble from an [apt package](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html#install-ros-2-packages) and sources it in the runtime
user's `.bashrc`. `ROS2_APT_PACKAGE` in `.env.ros2` selects the package set, defaulting to
`ros-base`. The image defaults to the `FastRTPS` middleware; `CycloneDDS` is also supported, and
both can be [tuned](https://docs.ros.org/en/foxy/How-To-Guides/DDS-tuning.html) through their `.xml` files under `docker/.ros`. See [various middleware](https://docs.ros.org/en/humble/How-To-Guides/Working-with-multiple-RMW-implementations.html)
for the trade-offs.

```text
# Source file not found: ../../../../docker/.env.ros2
```

## Kit-less image

The kit-less image drops Isaac Sim entirely and builds on Ubuntu 24.04 with Python 3.12. It carries
Newton physics, OVPhysX physics, OVRTX rendering, and the four core RL frameworks: RL Games, RSL-RL,
Stable-Baselines3, and SKRL. The `newton_gl`, `newton_rtx`, `viser`, and `rerun` visualizers are
included. Use `--viz newton_gl` for local visualization with a display available in the container.
`--viz newton_gl` selects the OpenGL rasterizer; `--viz newton_rtx` selects the OVRTX
path tracer. Both can render offscreen without Isaac Sim. To open their windows from a direct
`docker run`, run `xhost +local:` on the host and add `-e DISPLAY` and
`-v /tmp/.X11-unix:/tmp/.X11-unix:rw` to the command below. The deprecated `--viz newton` alias
selects GL; it does not choose between GL and RTX automatically.

Rendering needs NVIDIA graphics driver capabilities in addition to compute. For direct
`docker run` commands, pass `--gpus all -e NVIDIA_DRIVER_CAPABILITIES=all`. The NVIDIA
Container Toolkit exposes the host driver; avoid mounting a second copy of its Vulkan ICD.
If multiple drivers are discovered, select the NVIDIA ICD available inside the container
with `VK_DRIVER_FILES` (for example, `/etc/vulkan/icd.d/nvidia_icd.json`).

No visualizer is selected by default, so
training runs headless unless you ask for one. The `kit` visualizer is the exception: it comes from
Omniverse Kit, which this image does not contain.

Unlike the other two, it bind-mounts `apps` in addition to `source`, `scripts`, `tools`, and
`docs`, and it keeps a uv cache and a Warp cache of its own.

You do not have to build it locally. It is published alongside each Isaac Lab release in the same
registry repository, distinguished by a `-kitless` tag suffix:

```bash
docker pull nvcr.io/nvidia/isaac-lab:3.0.0-rc1-kitless
```

Running it directly, outside the Compose workflow, is a convenient way to verify the image and your
NVIDIA Container Toolkit setup. `--interactive` and `--tty` keep the container's shell alive so
that several commands can share it. The `isaac-lab-kitless-logs` named volume keeps checkpoints
after the container is removed:

```bash
docker run --name isaac-lab-kitless --detach --interactive --tty --gpus all --network host \
    -e NVIDIA_DRIVER_CAPABILITIES=all \
    -v isaac-lab-kitless-logs:/workspace/isaaclab/logs \
    nvcr.io/nvidia/isaac-lab:3.0.0-rc1-kitless

docker exec isaac-lab-kitless \
    isaaclab train --rl_library rsl_rl --task Isaac-Cartpole-Direct \
    --num_envs 16 presets=newton_mjwarp --max_iterations 5
```

Replay in a browser with:

```bash
docker exec --interactive --tty isaac-lab-kitless \
    isaaclab play --rl_library rsl_rl --task Isaac-Cartpole-Direct \
    --num_envs 16 presets=newton_mjwarp --checkpoint latest --viz viser
```

Viser is reachable through the host network without forwarding a desktop display. Stop playback
with `Ctrl+C` without stopping the container. Copy the logs to the host with
`docker cp isaac-lab-kitless:/workspace/isaaclab/logs ./logs`.

Check which architectures a tag publishes with `docker buildx imagetools inspect <image:tag>`
before choosing a host.

## Pre-built image from NGC

A minimal pre-built container carries a small set of Isaac Sim and Omniverse dependencies with Isaac
Lab already built in, under `/workspace/isaaclab`. The example below runs without a
forwarded desktop display. Choose the image profile for the physics and rendering stack
you need, and configure graphics access separately when rendering.

> **Note**
>
> Use an explicit published version tag for reproducible runs. The examples below use
> `3.0.0-rc1`; the corresponding kit-less image uses `3.0.0-rc1-kitless`.

> **Warning**
>
> Images from 3.0.0-beta2 onward run as a **non-root** user, so those bind-mount directories must be
> writable by uid/gid 1000. Docker creates any missing one as `root`, which the runtime user cannot
> write to, producing errors such as
> `PermissionError: [Errno 13] Permission denied: '/root/.local/share/ov/data/exts'`.
> Create them first:
>
> ```bash
> mkdir -p ~/docker/isaac-sim/{cache/kit,cache/ov,cache/pip,cache/glcache,cache/computecache,logs,data,documents}
> sudo chown -R 1000:1000 ~/docker/isaac-sim
> ```

Because it is run outside Compose, the Isaac Sim cache directories have to be mounted by hand,
otherwise every start recompiles shaders:

```bash
docker run --name isaac-lab --entrypoint bash -it --gpus all -e "ACCEPT_EULA=Y" --rm --network=host \
   -e "PRIVACY_CONSENT=Y" \
   -v ~/docker/isaac-sim/cache/kit:/isaac-sim/kit/cache:rw \
   -v ~/docker/isaac-sim/cache/ov:/root/.cache/ov:rw \
   -v ~/docker/isaac-sim/cache/pip:/root/.cache/pip:rw \
   -v ~/docker/isaac-sim/cache/glcache:/root/.cache/nvidia/GLCache:rw \
   -v ~/docker/isaac-sim/cache/computecache:/root/.nv/ComputeCache:rw \
   -v ~/docker/isaac-sim/logs:/root/.nvidia-omniverse/logs:rw \
   -v ~/docker/isaac-sim/data:/root/.local/share/ov/data:rw \
   -v ~/docker/isaac-sim/documents:/root/Documents:rw \
   nvcr.io/nvidia/isaac-lab:3.0.0-rc1
```

The command above opens no windows: without a display, `--viz kit`, `--viz newton_gl`, and
`--viz newton_rtx` run headless. The `viser` and `rerun` visualizers serve a web page instead
and need no display. To enable rendering through X11 forwarding, let local clients use the host X
server and pass the display into the container:

```bash
xhost +local:
docker run --name isaac-lab --entrypoint bash -it --gpus all -e "ACCEPT_EULA=Y" --rm --network=host \
   -e "PRIVACY_CONSENT=Y" \
   -e DISPLAY \
   -e MUJOCO_GL=disable \
   -v /tmp/.X11-unix:/tmp/.X11-unix:rw \
   -v ~/docker/isaac-sim/cache/kit:/isaac-sim/kit/cache:rw \
   -v ~/docker/isaac-sim/cache/ov:/root/.cache/ov:rw \
   -v ~/docker/isaac-sim/cache/pip:/root/.cache/pip:rw \
   -v ~/docker/isaac-sim/cache/glcache:/root/.cache/nvidia/GLCache:rw \
   -v ~/docker/isaac-sim/cache/computecache:/root/.nv/ComputeCache:rw \
   -v ~/docker/isaac-sim/logs:/root/.nvidia-omniverse/logs:rw \
   -v ~/docker/isaac-sim/data:/root/.local/share/ov/data:rw \
   -v ~/docker/isaac-sim/documents:/root/Documents:rw \
   nvcr.io/nvidia/isaac-lab:3.0.0-rc1
```

`xhost +local:` lets every local client use your display, not only the container; run
`xhost -local:` on the host to revoke it when you are done.
`MUJOCO_GL=disable` is needed by the Newton viewers in images released before it was set in the
image: those inherit `MUJOCO_GL=egl`, which fails the windowed viewer with
`Attempt to retrieve context when no valid context`. The Compose workflow sets up X11 forwarding
for you; see [Running Isaac Lab in Docker](/source/workflows/docker/index). Follow the graphics-driver requirements above for GL or RTX.

## Runtime user

The base, ROS 2, cuRobo, and kit-less images all run as a non-root user with uid/gid 1000. When
running one of these images directly with `docker run`, keep that default user instead of passing
`--user`, so that the runtime home and cache directories stay writable. Named volumes inherit the
image's ownership; make host bind mounts writable with `sudo chown -R 1000:1000 <directory>`.

## Python interpreter

Every image installs from `uv.lock` into a Python 3.12 virtual environment at
`/opt/isaaclab-venv`. On the Isaac Sim-based images the environment is built on Isaac Sim's own
interpreter, and Isaac Sim itself stays outside it, reached through the `_isaac_sim` symlink;
`isaaclab.sh` puts it on the path. In either case `python` on the container's `PATH` resolves
to the right one, so scripts are run the same way regardless of image.