Skip to content

Document non-root Docker volume fix for XR teleop startup#6061

Merged
AntoineRichard merged 1 commit into
isaac-sim:release/3.0.0-beta2from
rwiltz:rwiltz/cp/fix-xr-in-docker/release/3.0.0-beta2
Jun 9, 2026
Merged

Document non-root Docker volume fix for XR teleop startup#6061
AntoineRichard merged 1 commit into
isaac-sim:release/3.0.0-beta2from
rwiltz:rwiltz/cp/fix-xr-in-docker/release/3.0.0-beta2

Conversation

@rwiltz

@rwiltz rwiltz commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Description

Since the non-root Docker migration (#5618, first shipped in 3.0.0-beta2), the
container runs as user isaaclab (uid/gid 1000) with HOME=/root. Persistent
mounts at /root/.local/share/ov/data that were created by an older root-based
image (stale named volumes) or by Docker as auto-created bind-mount dirs are
owned by root, so the runtime user cannot write the extension-registry cache.
For XR teleop this aborts startup with a confusing, seemingly-unrelated error:
PermissionError: [Errno 13] Permission denied: '/root/.local/share/ov/data/exts'
...
No versions of omni.kit.xr.bundle.generic that satisfies: isaaclab.python.xr.openxr-3.0.0 ...
Exiting app because of dependency solver failure...
The XR bundle isn't actually missing — the registry never synced because its
cache dir couldn't be created. This PR documents the cause and fix:

docs/source/how-to/cloudxr_teleoperation.rst: adds an admonition to the
"Run with Docker" section explaining the failure and the fix (recreate/chown
volumes for Compose, pre-create/chown host dirs for single-container).
docs/source/deployment/docker.rst: warns that non-root prebuilt images
need bind-mount host dirs pre-created and chowned to uid/gid 1000, with a
copy-paste snippet.
Docs-only; no code changes and no changelog fragment (no source// package
touched).

Fixes # (issue)

Type of change

  • Documentation update

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with ./isaaclab.sh --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the changelog and the corresponding version in the extension's config/extension.toml file
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@github-actions github-actions Bot added bug Something isn't working documentation Improvements or additions to documentation labels Jun 9, 2026
@rwiltz rwiltz changed the title Fix XR in docker Document non-root Docker volume fix for XR teleop startup Jun 9, 2026
@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This documentation-only PR adds warning admonitions to the Docker guide and the CloudXR teleoperation guide explaining the permission-denied startup failure introduced by the 3.0.0-beta2 non-root container migration and how to resolve it.

  • docs/source/deployment/docker.rst: adds an attention block instructing users to pre-create and chown 1000:1000 the bind-mount host directories before running any non-root image, with a copy-paste mkdir -p / sudo chown snippet.
  • docs/source/how-to/cloudxr_teleoperation.rst: adds a detailed attention block reproducing the actual error cascade, explaining the root cause (cache dir write failure rather than a missing XR bundle), and providing two remediation paths — deleting/re-chowning Docker Compose named volumes or pre-chowning bind-mount host dirs for single-container setups.

Confidence Score: 4/5

Documentation-only change; no code is modified and no runtime behaviour changes.

Both files add helpful admonitions explaining a real permission issue. The two minor concerns — a Docker Compose fix bullet living inside a no-Compose section with a hardcoded volume name, and the warning appearing after a beta1 pull example — could leave some readers confused, but neither causes data loss or broken builds.

cloudxr_teleoperation.rst warrants a second look on the Docker Compose bullet scope and hardcoded volume name; docker.rst is straightforward once the pull-example ordering is considered.

Important Files Changed

Filename Overview
docs/source/deployment/docker.rst Adds an attention block warning that bind-mount host dirs must be pre-chowned for non-root images (3.0.0-beta2+); placement immediately after a beta1 pull example may confuse readers about which version the warning applies to.
docs/source/how-to/cloudxr_teleoperation.rst Adds a detailed attention block explaining the permission-denied / extension-registry failure and two fix paths; the Docker Compose fix bullet sits in a section that explicitly forbids Compose and uses a hardcoded volume name that may not match user environments.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User runs Isaac Lab Docker container] --> B{Image version?}
    B -- "≤ 3.0.0-beta1 (root user)" --> C[Writes to bind-mounts / named volumes normally]
    B -- "≥ 3.0.0-beta2 (uid/gid 1000)" --> D{Host dir / volume owned by root?}
    D -- No, already chowned --> E[Extension registry syncs OK\nXR session starts normally]
    D -- Yes, owned by root --> F["PermissionError: /root/.local/share/ov/data/exts"]
    F --> G[Extension registry sync fails]
    G --> H[Dependency solver failure — XR bundle 'missing']
    H --> I[App exits]
    I --> J{Fix path}
    J -- "Docker Compose volumes" --> K["docker compose down --volumes\n(or docker run alpine chown -R 1000:1000)"]
    J -- "Bind-mount host dirs" --> L["mkdir -p ~/docker/isaac-sim/...\nsudo chown -R 1000:1000 ~/docker/isaac-sim"]
    K --> E
    L --> E
Loading

Reviews (1): Last reviewed commit: "Fix XR in docker" | Re-trigger Greptile

Comment on lines +473 to +481
* **Docker Compose:** recreate the named volumes, e.g.

.. code-block:: bash

docker compose --file docker-compose.yaml --profile base --env-file .env.base down --volumes

See :ref:`deployment-docker` for details. To preserve cached data instead of
deleting it, ``chown`` the volume: ``docker run --rm -v docker_isaac-data:/data alpine
chown -R 1000:1000 /data``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Docker Compose option confusing in a no-Compose section

The paragraph just above this attention block explicitly tells users "Do not use Docker Compose", yet the first bullet here gives a docker compose down --volumes fix. A first-time reader following the guide would never have Compose-managed volumes; only 2.x-to-beta2 migrators would. Adding a short parenthetical like (only relevant if migrating from a 2.x Docker Compose setup) would make it clear this branch isn't for new setups. The hardcoded docker_isaac-data volume name also assumes the user's Compose project name is docker; the actual name depends on the directory the Compose file was run from. Suggesting docker volume ls first (or noting the naming convention) would prevent users from silently chowning the wrong volume.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines 325 to +341
docker pull nvcr.io/nvidia/isaac-lab:3.0.0-beta1

.. attention::

If the pre-built image you use runs as a **non-root** user (uid/gid 1000) -- as Isaac Lab
3.0.0-beta2 and later do -- the bind-mounted host directories below must be writable by that
user. Docker creates any missing bind-mount source directory as ``root``, which the non-root
runtime user cannot write to, leading to startup errors such as
``PermissionError: [Errno 13] Permission denied: '/root/.local/share/ov/data/exts'``.
Pre-create the host directories and make them writable by uid/gid 1000 before running the
container:

.. code:: 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Attention block placed after a beta1 pull example

The docker pull command immediately above uses 3.0.0-beta1, which is the last root-based image, so the attention block lands right after an example that doesn't actually need the chown fix. A user following this literally — pull beta1, see the warning, pre-chown dirs — will have done unnecessary work; a user who only skims may assume the warning doesn't apply and skip the chown when they later switch to beta2. Updating the pull example to 3.0.0-beta2 (or latest), or reordering so the attention appears before the pull command, would remove the ambiguity.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Documentation Review — PR #6061

Verdict: ✅ LGTM — Ship It

Summary

Clean, well-structured documentation update that explains a confusing non-root Docker permission failure and its fix. The PR addresses a real user pain point where the actual error (PermissionError on cache directory) manifests as a misleading "extension not found" message.

What's Good

  1. Clear problem statement: The admonitions explain why the failure happens (non-root uid/gid 1000 vs root-owned volumes) rather than just providing a magic fix.

  2. Actionable solutions: Both Docker Compose and single-container workflows get specific commands users can copy-paste.

  3. Error message examples: Including the actual error output (PermissionError, No versions of omni.kit.xr.bundle.generic) helps users recognize when this doc applies to their situation.

  4. Cross-reference: The XR teleop doc links to :ref:deployment-docker`` for additional context — good discoverability.

  5. Placement: Warnings are placed before the commands they affect, so users see them before hitting the error.

Minor Suggestions (Optional)

🔵 docker.rst:337 — The mkdir -p creates all subdirectories in a single command, which is a nice pattern. Consider adding a brief note that the exact subdirectory list matches the volume mounts in the docker run example below, so users understand the correspondence.

🔵 cloudxr_teleoperation.rst:479 — The alpine image for the chown trick is clever, but some users might be confused by the volume name docker_isaac-data. A brief note that Docker Compose prefixes volume names with the directory name could help.

No Issues Found

  • RST syntax is correct
  • Links and cross-references are properly formatted
  • No broken references or typos detected
  • Indentation is consistent

This review covers HEAD commit beca466.

@AntoineRichard

Copy link
Copy Markdown
Collaborator

This is not in develop. Is there any reason why it would be in beta 2 but not develop? Should we bring this to develop? I'm approving this, @rwiltz can you make sure this is also pushed to develop?

@AntoineRichard AntoineRichard merged commit b3f8fcf into isaac-sim:release/3.0.0-beta2 Jun 9, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants