Setup Workshop
brevdev/workshop-build-an-agent
This skill should be used when the user wants to set up, install, deploy, bootstrap, or "spin up" the Build-an-Agent workshop (a.k.a.
Best practices for Docker-based ROS2 development including multi-stage Dockerfiles, docker-compose for multi-container robotic systems, DDS discovery across containers, GPU passthrough for…
$ npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install arpitg1304/robotics-agent-skills docker-ros2-development --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/arpitg1304/robotics-agent-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/docker-ros2-development .claude/skills/docker-ros2-development && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "docker-ros2-development" agent skill from https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development into .claude/skills/docker-ros2-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "docker-ros2-development", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-developmentType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install arpitg1304/robotics-agent-skills docker-ros2-development --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/arpitg1304/robotics-agent-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/docker-ros2-development .agents/skills/docker-ros2-development && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "docker-ros2-development" agent skill from https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development into .agents/skills/docker-ros2-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "docker-ros2-development", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install arpitg1304/robotics-agent-skills docker-ros2-development --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/arpitg1304/robotics-agent-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/docker-ros2-development .cursor/skills/docker-ros2-development && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "docker-ros2-development" agent skill from https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development into .cursor/skills/docker-ros2-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "docker-ros2-development", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/arpitg1304/robotics-agent-skills.git --path skills/docker-ros2-development--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install arpitg1304/robotics-agent-skills docker-ros2-development --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/arpitg1304/robotics-agent-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/docker-ros2-development .gemini/skills/docker-ros2-development && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "docker-ros2-development" agent skill from https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development into .gemini/skills/docker-ros2-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "docker-ros2-development", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install arpitg1304/robotics-agent-skills docker-ros2-developmentInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/arpitg1304/robotics-agent-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/docker-ros2-development .github/skills/docker-ros2-development && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "docker-ros2-development" agent skill from https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development into .github/skills/docker-ros2-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "docker-ros2-development", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install arpitg1304/robotics-agent-skills docker-ros2-development --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/arpitg1304/robotics-agent-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/docker-ros2-development .opencode/skills/docker-ros2-development && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "docker-ros2-development" agent skill from https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development into .opencode/skills/docker-ros2-development/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "docker-ros2-development", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
docker-ros2-developmentBest practices for Docker-based ROS2 development including multi-stage Dockerfiles, docker-compose for multi-container robotic systems, DDS discovery across containers, GPU passthrough for…
Docker Ros2 Development is an agent skill from arpitg1304/robotics-agent-skills. Best practices for Docker-based ROS2 development including multi-stage Dockerfiles, docker-compose for multi-container robotic systems, DDS discovery across containers, GPU passthrough for perception, and dev-vs-deploy container patterns. Use this skill when containerizing ROS2 workspaces, setting up docker-compose for robot software stacks, debugging DDS communication between containers, configuring NVIDIA Container Toolkit for GPU workloads, forwarding X11/Wayland for rviz2 and GUI tools, or managing USB device…
Its SKILL.md is about 9.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in DevOps & Cloud, covering Containers. It works with Docker and NVIDIA AI Platform. The repository describes itself as: Agent skills that make AI coding assistants write production-grade robotics software. ROS1, ROS2, design patterns, SOLID principles, and testing — for Claude Code, Cursor… The licence is Apache-2.0.
8 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit f9bc546. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
dockerapt-getcurlpython3From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
cdds.ionvidia.github.ioeprosima.comraw.githubusercontent.compackages.ros.orgFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
GITHUB_TOKENFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Docker Ros2 Development loads about 9.1k tokens when it runs. Until then it costs about 260 tokens; SKILL.md has 1,181 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.listsudo apt-get update && sudo apt-get install -y nvidia-container-toolkitsudo nvidia-ctk runtime configure --runtime=dockersudo systemctl restart dockersudo udevadm control --reload-rules && sudo udevadm trigger8. **Environment injection** -- Use `.env` files or orchestrator secrets for `ROS_DOMAIN_ID`, DDS config paths, and deviAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from arpitg1304/robotics-agent-skills at commit f9bc546, republished under its Apache-2.0 licence (© arpitg1304). 1,181 words, ~9,071 tokens.
.claude/skills/docker-ros2-development/SKILL.md (or your agent's skills folder).Official OSRF images follow a layered hierarchy. Always choose the smallest base that satisfies dependencies.
┌──────────────────────────────────────────────────────────────────┐
│ ros:<distro>-desktop-full (~3.5 GB) │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ros:<distro>-desktop (~2.8 GB) │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ ros:<distro>-perception (~2.2 GB) │ │ │
│ │ │ ┌────────────────────────────────────────────────┐ │ │ │
│ │ │ │ ros:<distro>-ros-base (~1.1 GB) │ │ │ │
│ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ │
│ │ │ │ │ ros:<distro>-ros-core (~700 MB) │ │ │ │ │
│ │ │ │ └──────────────────────────────────────────┘ │ │ │ │
│ │ │ └────────────────────────────────────────────────┘ │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘| Image Tag | Base OS | Size | Contents | Use Case |
|---|---|---|---|---|
ros:humble-ros-core | Ubuntu 22.04 | ~700 MB | rclcpp, rclpy, rosout, launch | Minimal runtime for single nodes |
ros:humble-ros-base | Ubuntu 22.04 | ~1.1 GB | ros-core + common_interfaces, rosbag2 | Most production deployments |
ros:humble-perception | Ubuntu 22.04 | ~2.2 GB | ros-base + image_transport, cv_bridge, PCL | Camera/lidar perception pipelines |
ros:humble-desktop | Ubuntu 22.04 | ~2.8 GB | perception + rviz2, rqt, demos | Development with GUI tools |
ros:jazzy-ros-core | Ubuntu 24.04 | ~750 MB | rclcpp, rclpy, rosout, launch | Minimal runtime (Jazzy/Noble) |
ros:jazzy-ros-base | Ubuntu 24.04 | ~1.2 GB | ros-core + common_interfaces, rosbag2 | Production deployments (Jazzy) |
The development stage includes build tools, debuggers, and editor support for interactive use.
FROM ros:humble-desktop AS dev
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake gdb python3-pip \
python3-colcon-common-extensions python3-rosdep \
ros-humble-ament-lint-auto ros-humble-ament-cmake-pytest \
ccache \
&& rm -rf /var/lib/apt/lists/*
ENV CCACHE_DIR=/ccache
ENV CC="ccache gcc"
ENV CXX="ccache g++"Copies only src/ and package.xml files to maximize cache hits during dependency resolution.
FROM ros:humble-ros-base AS build
RUN apt-get update && apt-get install -y --no-install-recommends \
python3-colcon-common-extensions python3-rosdep \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /ros2_ws
# Copy package manifests first for dependency caching
COPY src/my_pkg/package.xml src/my_pkg/package.xml
RUN . /opt/ros/humble/setup.sh && apt-get update && \
rosdep install --from-paths src --ignore-src -r -y && \
rm -rf /var/lib/apt/lists/*
# Source changes invalidate only this layer and below
COPY src/ src/
RUN . /opt/ros/humble/setup.sh && \
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release \
--event-handlers console_direct+Contains only the built install space and runtime dependencies. No compilers, no source code.
FROM ros:humble-ros-core AS runtime
RUN apt-get update && apt-get install -y --no-install-recommends \
python3-yaml ros-humble-rmw-cyclonedds-cpp \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /ros2_ws/install /ros2_ws/install
RUN groupadd -r rosuser && useradd -r -g rosuser -m rosuser
USER rosuser
COPY ros_entrypoint.sh /ros_entrypoint.sh
ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["ros2", "launch", "my_pkg", "bringup.launch.py"]# syntax=docker/dockerfile:1
# Usage:
# docker build --target dev -t my_robot:dev .
# docker build --target runtime -t my_robot:latest .
ARG ROS_DISTRO=humble
ARG BASE_IMAGE=ros:${ROS_DISTRO}-ros-base
# Stage 1: Dependency base — install apt and rosdep deps
FROM ${BASE_IMAGE} AS deps
RUN apt-get update && apt-get install -y --no-install-recommends \
python3-colcon-common-extensions python3-rosdep \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /ros2_ws
# Copy only package.xml files for rosdep resolution (maximizes cache reuse)
COPY src/my_robot_bringup/package.xml src/my_robot_bringup/package.xml
COPY src/my_robot_perception/package.xml src/my_robot_perception/package.xml
COPY src/my_robot_msgs/package.xml src/my_robot_msgs/package.xml
COPY src/my_robot_navigation/package.xml src/my_robot_navigation/package.xml
RUN . /opt/ros/${ROS_DISTRO}/setup.sh && \
apt-get update && \
rosdep install --from-paths src --ignore-src -r -y && \
rm -rf /var/lib/apt/lists/*
# Stage 2: Development — full dev environment
FROM deps AS dev
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential gdb valgrind ccache python3-pip python3-pytest \
ros-${ROS_DISTRO}-ament-lint-auto \
ros-${ROS_DISTRO}-launch-testing-ament-cmake \
ros-${ROS_DISTRO}-rviz2 ros-${ROS_DISTRO}-rqt-graph \
&& rm -rf /var/lib/apt/lists/*
ENV CCACHE_DIR=/ccache CC="ccache gcc" CXX="ccache g++"
COPY src/ src/
COPY ros_entrypoint.sh /ros_entrypoint.sh
ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["bash"]
# Stage 3: Build — compile workspace
FROM deps AS build
COPY src/ src/
RUN . /opt/ros/${ROS_DISTRO}/setup.sh && \
colcon build \
--cmake-args -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF \
--event-handlers console_direct+ \
--parallel-workers $(nproc)
# Stage 4: Runtime — minimal production image
FROM ros:${ROS_DISTRO}-ros-core AS runtime
ARG ROS_DISTRO=humble
RUN apt-get update && apt-get install -y --no-install-recommends \
python3-yaml ros-${ROS_DISTRO}-rmw-cyclonedds-cpp \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /ros2_ws/install /ros2_ws/install
RUN groupadd -r rosuser && useradd -r -g rosuser -m -s /bin/bash rosuser
USER rosuser
ENV RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
COPY ros_entrypoint.sh /ros_entrypoint.sh
ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["ros2", "launch", "my_robot_bringup", "robot.launch.py"]The entrypoint script both dev and runtime stages use:
#!/bin/bash
set -e
source /opt/ros/${ROS_DISTRO}/setup.bash
if [ -f /ros2_ws/install/setup.bash ]; then
source /ros2_ws/install/setup.bash
fi
exec "$@"Each ROS2 subsystem runs in its own container with process isolation, independent scaling, and per-service resource limits.
# docker-compose.yml
version: "3.8"
x-ros-common: &ros-common
environment:
- ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
- CYCLONEDDS_URI=file:///cyclonedds.xml
volumes:
- ./config/cyclonedds.xml:/cyclonedds.xml:ro
- /dev/shm:/dev/shm
network_mode: host
restart: unless-stopped
services:
rosbridge:
<<: *ros-common
image: my_robot:latest
command: ros2 launch rosbridge_server rosbridge_websocket_launch.xml port:=9090
perception:
<<: *ros-common
image: my_robot_perception:latest
command: ros2 launch my_robot_perception perception.launch.py
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
devices:
- /dev/video0:/dev/video0 # USB camera passthrough
navigation:
<<: *ros-common
image: my_robot_navigation:latest
command: >
ros2 launch my_robot_navigation navigation.launch.py
use_sim_time:=false map:=/maps/warehouse.yaml
volumes:
- ./maps:/maps:ro
driver:
<<: *ros-common
image: my_robot_driver:latest
command: ros2 launch my_robot_driver driver.launch.py
devices:
- /dev/ttyUSB0:/dev/ttyUSB0 # Serial motor controller
- /dev/ttyACM0:/dev/ttyACM0 # IMU over USB-serial
group_add:
- dialoutservices:
driver:
<<: *ros-common
image: my_robot_driver:latest
healthcheck:
test: ["CMD", "bash", "-c",
"source /opt/ros/humble/setup.bash && ros2 topic list | grep -q /joint_states"]
interval: 5s
timeout: 10s
retries: 5
start_period: 15s
navigation:
<<: *ros-common
image: my_robot_navigation:latest
depends_on:
driver:
condition: service_healthy # Wait for driver topics
perception:
<<: *ros-common
image: my_robot_perception:latest
depends_on:
driver:
condition: service_healthy # Camera driver must be readyservices:
driver:
<<: *ros-common
image: my_robot_driver:latest
command: ros2 launch my_robot_driver driver.launch.py
rviz:
<<: *ros-common
profiles: ["dev"]
image: my_robot:dev
command: ros2 run rviz2 rviz2 -d /rviz/config.rviz
environment:
- DISPLAY=${DISPLAY}
- QT_X11_NO_MITSHM=1
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw
rosbag_record:
<<: *ros-common
profiles: ["dev"]
image: my_robot:dev
command: ros2 bag record -a --storage sqlite3 --max-bag-duration 300 -o /bags/session
volumes:
- ./bags:/bags
watchdog:
<<: *ros-common
profiles: ["deploy"]
image: my_robot:latest
command: ros2 launch my_robot_bringup watchdog.launch.py
restart: alwaysdocker compose --profile dev up # Dev tools (rviz, rosbag)
docker compose --profile deploy up -d # Production (watchdog, no GUI)When containers use bridge networking (no multicast), configure explicit unicast peer lists.
<!-- cyclonedds.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<CycloneDDS xmlns="https://cdds.io/config">
<Domain>
<General>
<Interfaces>
<NetworkInterface autodetermine="true" priority="default"/>
</Interfaces>
<AllowMulticast>false</AllowMulticast>
</General>
<Discovery>
<!-- Peer list uses docker-compose service names as hostnames -->
<Peers>
<Peer address="perception"/>
<Peer address="navigation"/>
<Peer address="driver"/>
<Peer address="rosbridge"/>
</Peers>
<ParticipantIndex>auto</ParticipantIndex>
<MaxAutoParticipantIndex>120</MaxAutoParticipantIndex>
</Discovery>
<Internal>
<SocketReceiveBufferSize min="10MB"/>
</Internal>
</Domain>
</CycloneDDS><!-- fastdds.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
<profiles>
<participant profile_name="docker_participant" is_default_profile="true">
<rtps>
<builtin>
<discovery_config>
<discoveryProtocol>SIMPLE</discoveryProtocol>
<leaseDuration><sec>10</sec></leaseDuration>
</discovery_config>
<initialPeersList>
<locator>
<udpv4><address>perception</address><port>7412</port></udpv4>
</locator>
<locator>
<udpv4><address>navigation</address><port>7412</port></udpv4>
</locator>
<locator>
<udpv4><address>driver</address><port>7412</port></udpv4>
</locator>
</initialPeersList>
</builtin>
</rtps>
</participant>
</profiles>
</dds>Mount and activate in compose:
# CycloneDDS
environment:
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
- CYCLONEDDS_URI=file:///cyclonedds.xml
volumes:
- ./config/cyclonedds.xml:/cyclonedds.xml:ro
# FastDDS
environment:
- RMW_IMPLEMENTATION=rmw_fastrtps_cpp
- FASTRTPS_DEFAULT_PROFILES_FILE=/fastdds.xml
volumes:
- ./config/fastdds.xml:/fastdds.xml:roDDS shared memory (zero-copy) requires /dev/shm sharing between containers. This provides highest throughput for large messages (images, point clouds).
services:
perception:
shm_size: "512m" # Default 64 MB is too small for image topics
volumes:
- /dev/shm:/dev/shm # Share host shm for inter-container zero-copy<!-- Enable shared memory in CycloneDDS -->
<CycloneDDS xmlns="https://cdds.io/config">
<Domain>
<SharedMemory>
<Enable>true</Enable>
</SharedMemory>
</Domain>
</CycloneDDS>Constraints: all communicating containers must share /dev/shm or use ipc: host. Use --ipc=shareable on one container and --ipc=container:<name> on others for scoped sharing.
services:
my_node:
network_mode: host # Shares host network namespace; DDS multicast works nativelyservices:
my_node:
networks: [ros_net]
networks:
ros_net:
driver: bridge # DDS multicast blocked; requires unicast peer confignetworks:
ros_macvlan:
driver: macvlan
driver_opts:
parent: eth0
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
services:
my_node:
networks:
ros_macvlan:
ipv4_address: 192.168.1.50 # Real LAN IP; DDS multicast works natively| Factor | Host | Bridge | Macvlan |
|---|---|---|---|
| DDS discovery | Works natively | Needs unicast peers | Works natively |
| Network isolation | None | Full isolation | LAN-level isolation |
| Port conflicts | Yes (host ports) | No (mapped ports) | No (unique IPs) |
| Performance | Native | Slight overhead | Near-native |
| Multi-host support | No | With overlay networks | Yes (same LAN) |
| When to use | Dev, single host | CI/CD, multi-tenant | Multi-robot on LAN |
# Install NVIDIA Container Toolkit on the host
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart dockerservices:
perception:
image: my_robot_perception:latest
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1 # Number of GPUs (or "all")
capabilities: [gpu]
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=compute,utility,video
shm_size: "1g" # Large shm for GPU<->CPU transfersFor Dockerfiles that need CUDA, start from NVIDIA base and install ROS2 on top:
FROM nvidia/cuda:12.2.0-cudnn8-runtime-ubuntu22.04 AS perception-base
RUN apt-get update && apt-get install -y --no-install-recommends \
curl gnupg2 lsb-release \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \
-o /usr/share/keyrings/ros-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \
http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" \
> /etc/apt/sources.list.d/ros2.list \
&& apt-get update && apt-get install -y --no-install-recommends \
ros-humble-ros-base ros-humble-cv-bridge ros-humble-image-transport \
&& rm -rf /var/lib/apt/lists/*docker compose exec perception bash -c '
nvidia-smi
python3 -c "import torch; print(f\"CUDA available: {torch.cuda.is_available()}\")"
'services:
rviz:
image: my_robot:dev
command: ros2 run rviz2 rviz2
environment:
- DISPLAY=${DISPLAY:-:0} # Forward host display
- QT_X11_NO_MITSHM=1 # Disable MIT-SHM (crashes in Docker)
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix:rw # X11 socket
- ${HOME}/.Xauthority:/root/.Xauthority:ro # Auth cookie
network_mode: host# Allow local Docker containers to access the X server
xhost +local:docker
# More secure variant:
xhost +SI:localuser:$(whoami)services:
rviz:
image: my_robot:dev
command: ros2 run rviz2 rviz2
environment:
- WAYLAND_DISPLAY=${WAYLAND_DISPLAY:-wayland-0}
- XDG_RUNTIME_DIR=/run/user/1000
- QT_QPA_PLATFORM=wayland
volumes:
- ${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}:/run/user/1000/${WAYLAND_DISPLAY}:rwFor CI/CD or remote machines without a physical display:
# Run rviz2 headless with Xvfb for screenshot capture or testing
docker run --rm my_robot:dev bash -c '
apt-get update && apt-get install -y xvfb mesa-utils &&
Xvfb :99 -screen 0 1920x1080x24 &
export DISPLAY=:99
source /opt/ros/humble/setup.bash
ros2 run rviz2 rviz2 -d /config/test.rviz --screenshot /output/frame.png
'Mount only src/ during development. Let colcon write build/, install/, and log/ inside named volumes to avoid bind mount performance issues.
# BAD: mounting entire workspace — build artifacts on bind mount are slow
# volumes:
# - ./my_ros2_ws:/ros2_ws
# GOOD: mount only source, use named volumes for build artifacts
services:
dev:
image: my_robot:dev
volumes:
- ./src:/ros2_ws/src:rw # Source code (bind mount)
- build_vol:/ros2_ws/build # Build artifacts (named volume)
- install_vol:/ros2_ws/install # Install space (named volume)
- log_vol:/ros2_ws/log # Log output (named volume)
working_dir: /ros2_ws
volumes:
build_vol:
install_vol:
log_vol:Persist ccache across container rebuilds for faster C++ compilation:
services:
dev:
volumes:
- ccache_vol:/ccache
environment:
- CCACHE_DIR=/ccache
- CCACHE_MAXSIZE=2G
- CC=ccache gcc
- CXX=ccache g++
volumes:
ccache_vol:Keep upstream packages cached and only rebuild custom packages:
# Stage 1: upstream dependencies (rarely changes)
FROM ros:humble-ros-base AS upstream
RUN apt-get update && apt-get install -y --no-install-recommends \
ros-humble-nav2-bringup ros-humble-slam-toolbox \
ros-humble-robot-localization \
&& rm -rf /var/lib/apt/lists/*
# Stage 2: custom packages overlay on top
FROM upstream AS workspace
WORKDIR /ros2_ws
COPY src/ src/
RUN . /opt/ros/humble/setup.sh && colcon build --symlink-install
# install/setup.bash automatically sources /opt/ros/humble as underlayservices:
camera_driver:
image: my_robot_driver:latest
devices:
- /dev/video0:/dev/video0 # USB camera (V4L2)
- /dev/video1:/dev/video1
group_add:
- video # Access /dev/videoN without root
motor_driver:
image: my_robot_driver:latest
devices:
- /dev/ttyUSB0:/dev/ttyUSB0 # USB-serial motor controller
- /dev/ttyACM0:/dev/ttyACM0 # Arduino/Teensy
group_add:
- dialout # Access serial ports without rootCreate stable device symlinks on the host so container paths remain consistent regardless of USB enumeration order.
# /etc/udev/rules.d/99-robot-devices.rules (host-side)
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="robot/motor_controller"
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="robot/lidar"
SUBSYSTEM=="video4linux", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="0825", SYMLINK+="robot/camera"sudo udevadm control --reload-rules && sudo udevadm triggerservices:
driver:
devices:
- /dev/robot/motor_controller:/dev/ttyMOTOR # Stable symlink
- /dev/robot/lidar:/dev/ttyLIDAR
- /dev/robot/camera:/dev/video0For devices plugged in after the container starts:
services:
driver:
# Option 1: privileged (use only when necessary)
privileged: true
volumes:
- /dev:/dev
# Option 2: cgroup device rules (more secure)
# device_cgroup_rules:
# - 'c 188:* rmw' # USB-serial (major 188)
# - 'c 81:* rmw' # Video devices (major 81)// .devcontainer/devcontainer.json
{
"name": "ROS2 Humble Dev",
"build": {
"dockerfile": "../Dockerfile",
"target": "dev",
"args": { "ROS_DISTRO": "humble" }
},
"runArgs": [
"--network=host", "--ipc=host", "--pid=host",
"--privileged", "--gpus", "all",
"-e", "DISPLAY=${localEnv:DISPLAY}",
"-e", "QT_X11_NO_MITSHM=1",
"-v", "/tmp/.X11-unix:/tmp/.X11-unix:rw",
"-v", "/dev:/dev"
],
"workspaceMount": "source=${localWorkspaceFolder},target=/ros2_ws/src,type=bind",
"workspaceFolder": "/ros2_ws",
"mounts": [
"source=ros2-build-vol,target=/ros2_ws/build,type=volume",
"source=ros2-install-vol,target=/ros2_ws/install,type=volume",
"source=ros2-log-vol,target=/ros2_ws/log,type=volume",
"source=ros2-ccache-vol,target=/ccache,type=volume"
],
"containerEnv": {
"ROS_DISTRO": "humble",
"RMW_IMPLEMENTATION": "rmw_cyclonedds_cpp",
"CCACHE_DIR": "/ccache",
"RCUTILS_COLORIZED_OUTPUT": "1"
},
"customizations": {
"vscode": {
"extensions": [
"ms-iot.vscode-ros",
"ms-vscode.cpptools",
"ms-python.python",
"ms-vscode.cmake-tools",
"smilerobotics.urdf",
"redhat.vscode-xml",
"redhat.vscode-yaml"
],
"settings": {
"ros.distro": "humble",
"python.defaultInterpreterPath": "/usr/bin/python3",
"C_Cpp.default.compileCommands": "/ros2_ws/build/compile_commands.json",
"cmake.configureOnOpen": false
}
}
},
"postCreateCommand": "sudo apt-get update && rosdep update && rosdep install --from-paths src --ignore-src -r -y",
"remoteUser": "rosuser"
}# .github/workflows/ros2-docker-ci.yml
name: ROS2 Docker CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-test:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
ros_distro: [humble, jazzy]
include:
- ros_distro: humble
ubuntu: "22.04"
- ros_distro: jazzy
ubuntu: "24.04"
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ matrix.ros_distro }}-${{ hashFiles('src/**/package.xml') }}
restore-keys: ${{ runner.os }}-buildx-${{ matrix.ros_distro }}-
- name: Build and test
run: |
docker build --target dev \
--build-arg ROS_DISTRO=${{ matrix.ros_distro }} \
-t test-image:${{ matrix.ros_distro }} .
docker run --rm test-image:${{ matrix.ros_distro }} bash -c '
source /opt/ros/${{ matrix.ros_distro }}/setup.bash &&
cd /ros2_ws &&
colcon build --cmake-args -DBUILD_TESTING=ON &&
colcon test --event-handlers console_direct+ &&
colcon test-result --verbose'
- name: Push runtime image
if: github.ref == 'refs/heads/main'
uses: docker/build-push-action@v5
with:
context: .
target: runtime
build-args: ROS_DISTRO=${{ matrix.ros_distro }}
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.ros_distro }}-latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.ros_distro }}-${{ github.sha }}
push: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
- name: Rotate cache
run: rm -rf /tmp/.buildx-cache && mv /tmp/.buildx-cache-new /tmp/.buildx-cacheOrder Dockerfile instructions from least-frequently-changed to most-frequently-changed:
1. Base image (ros:humble-ros-base) — changes on distro upgrade
2. System apt packages — changes on new dependency
3. rosdep install (from package.xml) — changes on new ROS dep
4. COPY src/ src/ — changes on every code edit
5. colcon build — rebuilds on source changestrategy:
matrix:
ros_distro: [humble, iron, jazzy, rolling]
rmw: [rmw_cyclonedds_cpp, rmw_fastrtps_cpp]
exclude:
- ros_distro: iron # Iron EOL — skip
rmw: rmw_fastrtps_cppProblem: Putting perception, navigation, planning, and drivers in a single container defeats the purpose of containerization. A crash in one subsystem takes down everything.
Fix: Split into one service per subsystem. Use docker-compose to orchestrate.
# BAD: monolithic container
services:
robot:
image: my_robot:latest
command: ros2 launch my_robot everything.launch.py
# GOOD: one container per subsystem
services:
perception:
image: my_robot_perception:latest
command: ros2 launch my_robot_perception perception.launch.py
navigation:
image: my_robot_navigation:latest
command: ros2 launch my_robot_navigation navigation.launch.py
driver:
image: my_robot_driver:latest
command: ros2 launch my_robot_driver driver.launch.pyProblem: DDS uses multicast for discovery by default. Docker bridge networks do not forward multicast. Nodes in different containers will not discover each other.
Fix: Use network_mode: host or configure DDS unicast peers explicitly.
# BAD: bridge network with no DDS config
services:
node_a:
networks: [ros_net]
node_b:
networks: [ros_net]
# GOOD: host networking (simplest)
services:
node_a:
network_mode: host
node_b:
network_mode: host
# GOOD: bridge with CycloneDDS unicast peers
services:
node_a:
networks: [ros_net]
environment:
- RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
- CYCLONEDDS_URI=file:///cyclonedds.xml
volumes:
- ./cyclonedds.xml:/cyclonedds.xml:roProblem: Installing compilers and build tools in the runtime image bloats it by 1-2 GB and increases attack surface.
Fix: Use multi-stage builds. Compile in a build stage, copy only the install space to runtime.
# BAD: build tools in runtime image (2.5 GB)
FROM ros:humble-ros-base
RUN apt-get update && apt-get install -y build-essential python3-colcon-common-extensions
COPY src/ /ros2_ws/src/
RUN cd /ros2_ws && colcon build
CMD ["ros2", "launch", "my_pkg", "bringup.launch.py"]
# GOOD: multi-stage build (800 MB)
FROM ros:humble-ros-base AS build
RUN apt-get update && apt-get install -y python3-colcon-common-extensions
COPY src/ /ros2_ws/src/
RUN cd /ros2_ws && . /opt/ros/humble/setup.sh && colcon build
FROM ros:humble-ros-core AS runtime
COPY --from=build /ros2_ws/install /ros2_ws/install
CMD ["ros2", "launch", "my_pkg", "bringup.launch.py"]Problem: Mounting the full workspace means colcon writes build/, install/, and log/ to a bind mount. On macOS/Windows Docker Desktop, bind mount I/O is 10-50x slower. Builds that take 2 minutes take 20+ minutes.
Fix: Mount only src/ as a bind mount. Use named volumes for build artifacts.
# BAD:
volumes:
- ./my_ros2_ws:/ros2_ws
# GOOD:
volumes:
- ./my_ros2_ws/src:/ros2_ws/src
- build_vol:/ros2_ws/build
- install_vol:/ros2_ws/install
- log_vol:/ros2_ws/logProblem: Running as root inside containers is a security risk. If compromised, the attacker has root access to mounted volumes and devices.
Fix: Create a non-root user with appropriate group membership.
# BAD:
FROM ros:humble-ros-base
COPY --from=build /ros2_ws/install /ros2_ws/install
CMD ["ros2", "launch", "my_pkg", "bringup.launch.py"]
# GOOD:
FROM ros:humble-ros-base
RUN groupadd -r rosuser && \
useradd -r -g rosuser -G video,dialout -m -s /bin/bash rosuser
COPY --from=build --chown=rosuser:rosuser /ros2_ws/install /ros2_ws/install
USER rosuser
CMD ["ros2", "launch", "my_pkg", "bringup.launch.py"]Problem: Placing COPY src/ . before rosdep install means every source change invalidates the dependency cache. All apt packages are re-downloaded on every build.
Fix: Copy only package.xml files first, install dependencies, then copy source.
# BAD: source copy before rosdep
COPY src/ /ros2_ws/src/
RUN rosdep install --from-paths src --ignore-src -r -y
RUN colcon build
# GOOD: package.xml first, then rosdep, then source
COPY src/my_pkg/package.xml /ros2_ws/src/my_pkg/package.xml
RUN . /opt/ros/humble/setup.sh && rosdep install --from-paths src --ignore-src -r -y
COPY src/ /ros2_ws/src/
RUN . /opt/ros/humble/setup.sh && colcon buildProblem: Hardcoding ROS_DOMAIN_ID=42 causes conflicts when multiple robots or developers share a network. Two robots with the same domain ID will cross-talk.
Fix: Use environment variables with defaults. Set domain ID at deploy time.
# BAD:
environment:
- ROS_DOMAIN_ID=42
# GOOD:
environment:
- ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}ROS_DOMAIN_ID=1 docker compose up -d # Robot 1
ROS_DOMAIN_ID=2 docker compose up -d # Robot 2Problem: The CMD runs ros2 launch ... but the shell has not sourced the ROS2 setup files. Fails with ros2: command not found.
Fix: Use an entrypoint script that sources the underlay and overlay before executing the command.
# BAD: no sourcing
FROM ros:humble-ros-core
COPY --from=build /ros2_ws/install /ros2_ws/install
CMD ["ros2", "launch", "my_pkg", "bringup.launch.py"]
# GOOD: entrypoint script handles sourcing
FROM ros:humble-ros-core
COPY --from=build /ros2_ws/install /ros2_ws/install
COPY ros_entrypoint.sh /ros_entrypoint.sh
RUN chmod +x /ros_entrypoint.sh
ENTRYPOINT ["/ros_entrypoint.sh"]
CMD ["ros2", "launch", "my_pkg", "bringup.launch.py"]#!/bin/bash
# ros_entrypoint.sh
set -e
source /opt/ros/${ROS_DISTRO}/setup.bash
if [ -f /ros2_ws/install/setup.bash ]; then
source /ros2_ws/install/setup.bash
fi
exec "$@"rosuser with only the group memberships needed (video, dialout) instead of privileged modecyclonedds.xml or fastdds.xml with explicit peer lists if not using host networkingmem_limit, cpus, and GPU reservations for each service to prevent resource starvationrestart: unless-stopped for all services and restart: always for critical drivers and watchdogs.env files or orchestrator secrets for ROS_DOMAIN_ID, DDS config paths, and device mappings rather than hardcodingshm_size to at least 256 MB (512 MB for image topics) and configure DDS shared memory transport for high-bandwidth topics/dev/robot/* symlinks and reference those in compose device mappingslatest and a commit SHA or semantic version; never deploy unversioned latest to production© arpitg1304, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/docker-ros2-development of arpitg1304/robotics-agent-skills.
Open the folder on GitHubat commit f9bc546
Docker Ros2 Development next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Docker Ros2 Development this skillarpitg1304/robotics-agent-skills | 368 | — | ~9.1k | Automated safety check: Notes | Apache-2.0 | |
| Setup Workshopbrevdev/workshop-build-an-agent | 143 | — | ~2.3k | Automated safety check: Notes | Apache-2.0 | |
| Generate Nemo Gym Envadithya-s-k/FineEnvs | 421 | — | ~2.1k | Automated safety check: Pass | Apache-2.0 | |
| Init GPU Serverdrawthingsai/draw-things-community | 579 | — | ~2.2k | Automated safety check: Pass | GPL-3.0 | |
| Upgrade Depsareal-project/AReaL | 5.8k | — | ~6k | Automated safety check: Pass | Apache-2.0 | |
| Evo2 NimNVIDIA/skills | 3.5k | 1 repos | ~2.4k | Automated safety check: Notes | Apache-2.0 |
brevdev/workshop-build-an-agent
This skill should be used when the user wants to set up, install, deploy, bootstrap, or "spin up" the Build-an-Agent workshop (a.k.a.
adithya-s-k/FineEnvs
Builds a NeMo Gym (NVIDIA) variant of an RL environment. An agent skill from adithya-s-k/FineEnvs.
drawthingsai/draw-things-community
Initialize a Draw Things GPU server with GPUScript, including script sync, Docker/CUDA/NVIDIA runtime setup, 7T data disk mounting, mergerfs, and end-to-end GPU verification.
areal-project/AReaL
Upgrade focused runtime dependencies in AReaL. An agent skill from areal-project/AReaL.
NVIDIA/skills
Generate and analyze DNA sequences using NVIDIA's Evo 2 BioNeMo NIM microservice.
NVIDIA/skills
Generate multiple sequence alignments (MSAs) for protein sequences using the ColabFold MSA-Search NIM.
arpitg1304/robotics-agent-skills
Testing strategies, patterns, and tools for robotics software.
arpitg1304/robotics-agent-skills
Best practices, design patterns, and common pitfalls for ROS1 (Robot Operating System 1) development.
arpitg1304/robotics-agent-skills
Bringing up a complete ROS2 system on a robot's onboard computer: systemd services, launch file composition, ordered startup, and production monitoring.
arpitg1304/robotics-agent-skills
Comprehensive best practices for robot perception systems covering cameras, LiDARs, depth sensors, IMUs, and multi-sensor setups.
arpitg1304/robotics-agent-skills
Architecture patterns, design principles, and proven recipes for building robust robotics software.
arpitg1304/robotics-agent-skills
Foundational software design principles applied specifically to robotics module development.
Works with
Categories
Best practices for Docker-based ROS2 development including multi-stage Dockerfiles, docker-compose for multi-container robotic systems, DDS discovery across containers, GPU passthrough for…. Docker Ros2 Development is an agent skill from arpitg1304/robotics-agent-skills. Best practices for Docker-based ROS2 development including multi-stage Dockerfiles, docker-compose for multi-container robotic systems, DDS discovery across containers, GPU passthrough for perception, and dev-vs-deploy container patterns.
Docker Ros2 Development fits situations like: containerizing ROS2 workspaces; setting up docker-compose for robot software stacks; debugging DDS communication between containers; configuring NVIDIA Container Toolkit for GPU workloads.
Run `npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a claude-code`. Or copy the skill folder (skills/docker-ros2-development in arpitg1304/robotics-agent-skills) into .claude/skills/docker-ros2-development in your project. Claude Code loads it when a task matches its description.
Run `npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a codex`. Or copy the skill folder (skills/docker-ros2-development in arpitg1304/robotics-agent-skills) into .agents/skills/docker-ros2-development in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add arpitg1304/robotics-agent-skills --skill docker-ros2-development -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/docker-ros2-development, .gemini/skills/docker-ros2-development, .github/skills/docker-ros2-development and .opencode/skills/docker-ros2-development in your project.
Going by SKILL.md and its folder, Docker Ros2 Development needs the command-line tools its instructions call (docker, apt-get, curl and python3) and credentials named GITHUB_TOKEN. Our summary lists: Docker.
SKILL.md names 5 domains. In commands or code: cdds.io, nvidia.github.io, eprosima.com, raw.githubusercontent.com and packages.ros.org; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (runs commands with sudo; mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Docker Ros2 Development is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 9.1k tokens (SKILL.md is roughly 36k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Docker Ros2 Development: Setup Workshop (brevdev/workshop-build-an-agent, 143 stars), Generate Nemo Gym Env (adithya-s-k/FineEnvs, 421 stars), Init GPU Server (drawthingsai/draw-things-community, 579 stars) and Upgrade Deps (areal-project/AReaL, 5.8k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
arpitg1304 (a GitHub user) maintains it in arpitg1304/robotics-agent-skills, which has 368 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on August 12, 2026.
Source: arpitg1304/robotics-agent-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.