03 · Deployment
Previous: 02-Environment-SetupNext, pick a path: xlerobot/ (whole XLeRobot) or lerobot/ (single arm / LeKiwi)
Pull the image onto your machine and start the container. Once you've finished this page, you'll be inside a shell with the whole environment ready.
1. Get the image
There is exactly one image:
docker pull chenyang310/xlerobot:jetson| Architecture | arm64 |
| Runs on | Jetson + JetPack 7.2 |
| Download | ~3.6 GB (larger once unpacked — leave 20 GB free) |
| Includes | Teleoperation, calibration, data recording, training and inference, GPU-accelerated |
Confirm it arrived:
docker images | grep xlerobotYou should see chenyang310/xlerobot with the jetson tag.
Mainland China: this pulls fine as-is — no registry mirror needed. If it's slow, see 02-Environment-Setup, section 2.
Building it yourself (maintainers)
For when you need to make changes, or want to build from the latest source.
git clone <repository-url> xlerobot-docker
cd xlerobot-docker
bash scripts/build.sh jetsonThe build script already points at China-region sources (Aliyun PyPI, Aliyun Ubuntu mirrors), so you can build on a mainland-China network with no extra configuration.
The first build downloads about 2 GB of dependencies — one to two hours on a slow connection. Use
scripts/sync.shplus thewheels/cache on the board to reuse already-downloaded packages.
2. What's in the image
One image, everything included:
- Teleoperation and calibration — drive the robot by hand and save its calibration
- Data recording and replay
- Training — ACT, Diffusion Policy, SmolVLA, π₀, π₀.₅, Wall-OSS
- Inference — run a trained policy on the robot, GPU-accelerated
3. Start the container
3.1 Start with the script (recommended)
If you cloned the repository:
bash scripts/run.sh jetsonThe script already configures:
- GPU —
--device nvidia.com/gpu=all(CDI) - Device passthrough — serial ports, cameras, USB
- Networking —
--network host, needed for VR teleoperation and web control - Source mount — edit code without rebuilding the image
- Cache mount — calibration files and model downloads are kept
3.2 Start manually
If you're not using the script, the minimal working command:
docker run -it --rm \
--name xlerobot \
--device nvidia.com/gpu=all \
--privileged \
--network host \
-v /dev:/dev \
-v ~/.cache/huggingface:/home/jetson/.cache/huggingface \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e DISPLAY=$DISPLAY \
-e HF_ENDPOINT=https://hf-mirror.com \
chenyang310/xlerobot:jetsonWhat each flag does:
| Flag | Why it's needed |
|---|---|
--device nvidia.com/gpu=all | Gives the container the GPU (via CDI). Without it there is no GPU at all |
--privileged + -v /dev:/dev | Serial ports (SO-101 servos), cameras, USB passthrough |
--network host | host/client two-process communication (ZMQ), plus VR control |
-v ~/.cache/huggingface | Calibration files and model cache. Without it, you recalibrate every time the container restarts |
-v /tmp/.X11-unix + -e DISPLAY | For running visualization (opening the rerun window) |
-e HF_ENDPOINT | huggingface.co is completely unreachable from mainland China — the mirror is mandatory |
The
/home/jetsonin the mount path is the user directory inside the image — hard-coding it is correct, because that image's user is namedjetson.
Inside you get a bash shell with the working directory /opt/xlerobot.
4. GPU flags — the CDI way
The image must be given the GPU via CDI — --runtime nvidia can't be used:
docker run -it --rm \
--device nvidia.com/gpu=all \
--privileged --network host -v /dev:/dev \
... \
chenyang310/xlerobot:jetsonBefore first use, generate the CDI spec on the host:
sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml
sudo systemctl restart dockerPitfall we hit: on JetPack 7.2, the
enable-cuda-compathook innvidia-container-toolkit 1.19.1crashes (slice bounds out of range), so the container won't start at all. Disable it by adding a flag:bashsudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml \ --disable-hook enable-cuda-compatWhen the container's CUDA version matches the host's, you don't need this hook.
Verify the GPU works
python -c "import torch; print('GPU:', torch.cuda.is_available())"5. Platform-specific notes
Jetson Orin series — ✅ Currently officially supported
| Model | Requires | Notes |
|---|---|---|
| Orin Nano | JetPack 7.2 | The board we tested on (teleoperation runs even on 3.4 GB of memory) |
| Orin NX | JetPack 7.2 | Same as above |
| AGX Orin / AGX Orin 64GB | JetPack 7.2 | ⚠️ 7.0 / 7.1 don't support AGX Orin 64GB — 7.2 is required |
The only hard requirement is the JetPack version: the torch in the image is compiled for CUDA 13.0, and CUDA 13.x requires a driver ≥ 580.
| JetPack | L4T | CUDA | Driver | Usable? |
|---|---|---|---|---|
| 6.2 | 36.4.3 | 12.6 | 540.4.0 | ❌ Driver too old |
| 7.2 | 39.2 | 13.2 | 595 series | ✅ |
Check your version:
cat /etc/nv_tegra_release
dpkg -l | grep nvidia-jetpack⚠️ Upgrading from JetPack 6.x to 7.x can't be done via
apt upgrade/ OTA (OTA only works within the same major L4T version) — a full reflash is required.
Jetson Nano (2019 original) — ❌ Never supported
Three independent reasons, all dead ends:
- CUDA 13 removed the Maxwell architecture entirely. Driver R580 is the last branch to support Maxwell / Pascal / Volta, and CUDA 13 requires exactly 580+. The Jetson Nano can't get past JetPack 4.6.6 / CUDA 10.2 at best.
- Compute capability 5.3 is below torch's supported floor. The architectures torch is compiled for in this image are
sm_80 / sm_90 / sm_100 / sm_110 / sm_120— sm_80 is the lowest — while the Jetson Nano is sm_53, so there's no native kernel for it and PTX JIT can't reach it either. - The platform is EOL (JetPack 4 stopped receiving maintenance in November 2024).
Any other platform — ❌ Not supported
Raspberry Pi, ordinary x86 PCs, Windows and macOS cannot run this image. It is built against JetPack 7.2's CUDA stack and shipped as arm64 only, so there is no CPU edition to fall back to. Use a Jetson Orin board.
Check what you have:
uname -mshould printaarch64, andcat /etc/nv_tegra_releaseshould report R39.
After entering the container
Run a self-check first:
python -c "import torch, lerobot; print('torch', torch.__version__); print('lerobot', lerobot.__version__)"Expected output:
torch 2.11.0+cu130
lerobot 0.6.2⚠️
xlerobotandxlerobot_mecanumcan't go in the same process — both register as"xlerobot"in the source (the mecanum config was copied and its registration name was never changed). This is an upstream XLeRobot bug, and it reportsCannot register ... as xlerobot because ... already registered.Every other combination is fine: original LeRobot robots and XLeRobot can coexist in the same process (8 types registered together successfully in testing), and
xlerobot_2wheelsdoesn't collide either. One robot only ever uses one variant, so normal use is unaffected.
Next, pick a path: xlerobot/ whole XLeRobot · lerobot/ single arm / LeKiwi

