Add Install, Docker Build, and CI for a New Model or Environment
Use this skill when adding a new model or new environment (or combination) to RLinf so that: (1) users can install it via requirements/install.sh, (2) a Docker image can be built for it (optional), (3) CI runs a Docker build and an end-to-end test.
1. Install script (requirements/install.sh)
- New model: add to SUPPORTEDMODELS (e.g. "dexbotic"). - New environment: add to SUPPORTEDENVS (e.g. "maniskill_libero").
- New model: add install<model>model() that switches on ENVNAME and for each supported env: create venv, install common embodied deps, env-specific deps, and the model. Call it from the main case "$MODEL" (add a new modelname) branch that runs install<model>model). - New env only (no new model): either add a new env branch inside an existing install*model() or add install<env>env() and call it from the relevant model installers. If the env is used by installenvonly, add a branch in installenvonly for that env.
printhelp shows SUPPORTEDMODELS and SUPPORTED_ENVS; no change needed if you only added to those arrays.
See [reference.md](reference.md) for exact variable names and code patterns.
2. Dockerfile (docker/Dockerfile)
If the combo needs a different base (e.g. Ubuntu 20 for ROS/Franka), add: FROM <base> AS base-image-embodied-<target> Otherwise reuse: FROM nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04 AS base-image-embodied-<target>.
Add a stage: - FROM embodied-common-image AS embodied-<target>-image - Single RUN for all installs: If the image installs multiple envs (multiple model+env or venvs), chain every install.sh call in one RUN with &&. Splitting installs across multiple RUN layers breaks uv’s hardlink mode (UVLINKMODE=hardlink), because the cache from the previous layer is not in the same layer for hardlinking. Example: RUN bash requirements/install.sh embodied --venv openvla --model openvla --env maniskilllibero && \ then bash requirements/install.sh embodied --venv openpi --model openpi --env maniskilllibero. - Any asset download/link in the same or a following RUN; then RUN echo "source \${UV_PATH}/<venv>/bin/activate" >> ~/.bashrc for default env.
The last stage is FROM ${BUILDTARGET}-image AS final-image. Valid BUILDTARGET values are those that have a matching *-image stage (e.g. reason, embodied-maniskilllibero, embodied-dexbotic-maniskilllibero). Adding a new stage makes the new target valid; no change to the final stage line.
Naming: BUILDTARGET is typically embodied-<env> (e.g. embodied-maniskilllibero) or embodied-<env>-<model> when one image combines multiple models (e.g. behavior-openvlaoft). Match the pattern used by existing stages.
3. CI: Docker build (.github/workflows/docker-build.yml)
Add a job that builds the new image:
- Job id:
build-embodied-<target> (same <target> as in Dockerfile stage name, e.g. build-embodied-maniskill_libero).
- Reuse the same steps as existing jobs: maximize storage, checkout, setup Docker Buildx, then build with
BUILDTARGET=embodied-<target>, NOMIRROR=true, outputs: type=cacheonly, and a tag like rlinf:embodied-<target>.
Copy an existing build-embodied-* job and replace the target name. See [reference.md](reference.md).
4. CI: Embodied e2e test (.github/workflows/embodied-e2e-tests.yml)
Add a YAML config under tests/e2etests/embodied/ (e.g. <env><algo><model>.yaml). The e2e runner is trainembodied_agent.py with --config-name <name>; the config name is the filename without .yaml.
Add a job (e.g. embodied-<model>-<env>-test): - Checkout. - Create embodied environment: set UV*, any required path env vars (e.g. GR00TPATH, BEHAVIORPATH), then bash requirements/install.sh embodied --model <model> --env <env>. - Run test: source .venv/bin/activate, set REPOPATH, then bash tests/e2etests/embodied/run.sh <configname> (or run_async.sh if the test is async). Use a reasonable timeout-minutes. - Clean up: rm -rf .venv, uv cache prune, and any test-specific cleanup.
Use runs-on: embodied so the job runs on a runner with GPU/datasets. See existing jobs in the file for env vars and step order.
Checklist