Document non-root Docker volume fix for XR teleop startup#6061
Conversation
Greptile SummaryThis 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.
Confidence Score: 4/5Documentation-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
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
Reviews (1): Last reviewed commit: "Fix XR in docker" | Re-trigger Greptile |
| * **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``. |
There was a problem hiding this comment.
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!
| 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 | ||
|
|
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
📋 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
-
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.
-
Actionable solutions: Both Docker Compose and single-container workflows get specific commands users can copy-paste.
-
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. -
Cross-reference: The XR teleop doc links to
:ref:deployment-docker`` for additional context — good discoverability. -
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.
|
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? |
b3f8fcf
into
isaac-sim:release/3.0.0-beta2
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
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfileCONTRIBUTORS.mdor my name already exists there