🧪 New tutorials are being published — build from robot arms to sensors step by step
Skip to content

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:

bash
docker pull chenyang310/xlerobot:jetson
Architecturearm64
Runs onJetson + JetPack 7.2
Download~3.6 GB (larger once unpacked — leave 20 GB free)
IncludesTeleoperation, calibration, data recording, training and inference, GPU-accelerated

Confirm it arrived:

bash
docker images | grep xlerobot

You 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.

bash
git clone <repository-url> xlerobot-docker
cd xlerobot-docker

bash scripts/build.sh jetson

The 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.sh plus the wheels/ 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 ​

If you cloned the repository:

bash
bash scripts/run.sh jetson

The 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:

bash
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:jetson

What each flag does:

FlagWhy it's needed
--device nvidia.com/gpu=allGives the container the GPU (via CDI). Without it there is no GPU at all
--privileged + -v /dev:/devSerial ports (SO-101 servos), cameras, USB passthrough
--network hosthost/client two-process communication (ZMQ), plus VR control
-v ~/.cache/huggingfaceCalibration files and model cache. Without it, you recalibrate every time the container restarts
-v /tmp/.X11-unix + -e DISPLAYFor running visualization (opening the rerun window)
-e HF_ENDPOINThuggingface.co is completely unreachable from mainland China — the mirror is mandatory

The /home/jetson in the mount path is the user directory inside the image — hard-coding it is correct, because that image's user is named jetson.

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:

bash
docker run -it --rm \
  --device nvidia.com/gpu=all \
  --privileged --network host -v /dev:/dev \
  ... \
  chenyang310/xlerobot:jetson

Before first use, generate the CDI spec on the host:

bash
sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml
sudo systemctl restart docker

Pitfall we hit: on JetPack 7.2, the enable-cuda-compat hook in nvidia-container-toolkit 1.19.1 crashes (slice bounds out of range), so the container won't start at all. Disable it by adding a flag:

bash
sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml \
  --disable-hook enable-cuda-compat

When the container's CUDA version matches the host's, you don't need this hook.

Verify the GPU works ​

bash
python -c "import torch; print('GPU:', torch.cuda.is_available())"

5. Platform-specific notes ​

Jetson Orin series — ✅ Currently officially supported ​

ModelRequiresNotes
Orin NanoJetPack 7.2The board we tested on (teleoperation runs even on 3.4 GB of memory)
Orin NXJetPack 7.2Same as above
AGX Orin / AGX Orin 64GBJetPack 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.

JetPackL4TCUDADriverUsable?
6.236.4.312.6540.4.0❌ Driver too old
7.239.213.2595 series✅

Check your version:

bash
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:

  1. 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.
  2. 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.
  3. 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 -m should print aarch64, and cat /etc/nv_tegra_release should report R39.


After entering the container ​

Run a self-check first:

bash
python -c "import torch, lerobot; print('torch', torch.__version__); print('lerobot', lerobot.__version__)"

Expected output:

torch 2.11.0+cu130
lerobot 0.6.2

⚠️ xlerobot and xlerobot_mecanum can'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 reports Cannot 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_2wheels doesn'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