{"id":"a3416e77-997c-47c7-a2b4-f39d3d9ba1b9","shortId":"kGtfun","kind":"skill","title":"docker-ros2-development","tagline":"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 w","description":"# Docker-Based ROS2 Development Skill\n\n## When to Use This Skill\n\n- Writing Dockerfiles for ROS2 workspaces with colcon builds\n- Setting up docker-compose for multi-container robotic systems\n- Debugging DDS discovery failures between containers (CycloneDDS, FastDDS)\n- Configuring GPU passthrough with NVIDIA Container Toolkit for perception nodes\n- Forwarding X11 or Wayland displays for rviz2 and rqt tools\n- Managing USB device passthrough for cameras, LiDARs, and serial devices\n- Building CI/CD pipelines with Docker-based ROS2 builds and test runners\n- Creating devcontainer configurations for VS Code with ROS2 extensions\n- Optimizing Docker layer caching for colcon workspace builds\n- Designing dev-vs-deploy container strategies with multi-stage builds\n\n## ROS2 Docker Image Hierarchy\n\nOfficial OSRF images follow a layered hierarchy. Always choose the smallest base that satisfies dependencies.\n\n```\n┌──────────────────────────────────────────────────────────────────┐\n│  ros:<distro>-desktop-full  (~3.5 GB)                            │\n│  ┌────────────────────────────────────────────────────────────┐  │\n│  │  ros:<distro>-desktop     (~2.8 GB)                        │  │\n│  │  ┌──────────────────────────────────────────────────────┐  │  │\n│  │  │  ros:<distro>-perception (~2.2 GB)                    │  │  │\n│  │  │  ┌────────────────────────────────────────────────┐   │  │  │\n│  │  │  │  ros:<distro>-ros-base  (~1.1 GB)              │   │  │  │\n│  │  │  │  ┌──────────────────────────────────────────┐  │   │  │  │\n│  │  │  │  │  ros:<distro>-ros-core (~700 MB)         │  │   │  │  │\n│  │  │  │  └──────────────────────────────────────────┘  │   │  │  │\n│  │  │  └────────────────────────────────────────────────┘   │  │  │\n│  │  └──────────────────────────────────────────────────────┘  │  │\n│  └────────────────────────────────────────────────────────────┘  │\n└──────────────────────────────────────────────────────────────────┘\n```\n\n| Image Tag               | Base OS        | Size    | Contents                                    | Use Case                            |\n|--------------------------|----------------|---------|---------------------------------------------|-------------------------------------|\n| `ros:humble-ros-core`    | Ubuntu 22.04   | ~700 MB | rclcpp, rclpy, rosout, launch               | Minimal runtime for single nodes    |\n| `ros:humble-ros-base`    | Ubuntu 22.04   | ~1.1 GB | ros-core + common_interfaces, rosbag2       | Most production deployments         |\n| `ros:humble-perception`  | Ubuntu 22.04   | ~2.2 GB | ros-base + image_transport, cv_bridge, PCL  | Camera/lidar perception pipelines   |\n| `ros:humble-desktop`     | Ubuntu 22.04   | ~2.8 GB | perception + rviz2, rqt, demos              | Development with GUI tools          |\n| `ros:jazzy-ros-core`     | Ubuntu 24.04   | ~750 MB | rclcpp, rclpy, rosout, launch               | Minimal runtime (Jazzy/Noble)       |\n| `ros:jazzy-ros-base`     | Ubuntu 24.04   | ~1.2 GB | ros-core + common_interfaces, rosbag2       | Production deployments (Jazzy)      |\n\n## Multi-Stage Dockerfiles for ROS2\n\n### Dev Stage\n\nThe development stage includes build tools, debuggers, and editor support for interactive use.\n\n```dockerfile\nFROM ros:humble-desktop AS dev\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    build-essential cmake gdb python3-pip \\\n    python3-colcon-common-extensions python3-rosdep \\\n    ros-humble-ament-lint-auto ros-humble-ament-cmake-pytest \\\n    ccache \\\n    && rm -rf /var/lib/apt/lists/*\nENV CCACHE_DIR=/ccache\nENV CC=\"ccache gcc\"\nENV CXX=\"ccache g++\"\n```\n\n### Build Stage\n\nCopies only `src/` and `package.xml` files to maximize cache hits during dependency resolution.\n\n```dockerfile\nFROM ros:humble-ros-base AS build\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    python3-colcon-common-extensions python3-rosdep \\\n    && rm -rf /var/lib/apt/lists/*\nWORKDIR /ros2_ws\n# Copy package manifests first for dependency caching\nCOPY src/my_pkg/package.xml src/my_pkg/package.xml\nRUN . /opt/ros/humble/setup.sh && apt-get update && \\\n    rosdep install --from-paths src --ignore-src -r -y && \\\n    rm -rf /var/lib/apt/lists/*\n# Source changes invalidate only this layer and below\nCOPY src/ src/\nRUN . /opt/ros/humble/setup.sh && \\\n    colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release \\\n      --event-handlers console_direct+\n```\n\n### Runtime Stage\n\nContains only the built install space and runtime dependencies. No compilers, no source code.\n\n```dockerfile\nFROM ros:humble-ros-core AS runtime\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    python3-yaml ros-humble-rmw-cyclonedds-cpp \\\n    && rm -rf /var/lib/apt/lists/*\nCOPY --from=build /ros2_ws/install /ros2_ws/install\nRUN groupadd -r rosuser && useradd -r -g rosuser -m rosuser\nUSER rosuser\nCOPY ros_entrypoint.sh /ros_entrypoint.sh\nENTRYPOINT [\"/ros_entrypoint.sh\"]\nCMD [\"ros2\", \"launch\", \"my_pkg\", \"bringup.launch.py\"]\n```\n\n### Full Multi-Stage Dockerfile\n\n```dockerfile\n# syntax=docker/dockerfile:1\n# Usage:\n#   docker build --target dev -t my_robot:dev .\n#   docker build --target runtime -t my_robot:latest .\nARG ROS_DISTRO=humble\nARG BASE_IMAGE=ros:${ROS_DISTRO}-ros-base\n\n# Stage 1: Dependency base — install apt and rosdep deps\nFROM ${BASE_IMAGE} AS deps\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    python3-colcon-common-extensions python3-rosdep \\\n    && rm -rf /var/lib/apt/lists/*\nWORKDIR /ros2_ws\n# Copy only package.xml files for rosdep resolution (maximizes cache reuse)\nCOPY src/my_robot_bringup/package.xml src/my_robot_bringup/package.xml\nCOPY src/my_robot_perception/package.xml src/my_robot_perception/package.xml\nCOPY src/my_robot_msgs/package.xml src/my_robot_msgs/package.xml\nCOPY src/my_robot_navigation/package.xml src/my_robot_navigation/package.xml\nRUN . /opt/ros/${ROS_DISTRO}/setup.sh && \\\n    apt-get update && \\\n    rosdep install --from-paths src --ignore-src -r -y && \\\n    rm -rf /var/lib/apt/lists/*\n\n# Stage 2: Development — full dev environment\nFROM deps AS dev\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    build-essential gdb valgrind ccache python3-pip python3-pytest \\\n    ros-${ROS_DISTRO}-ament-lint-auto \\\n    ros-${ROS_DISTRO}-launch-testing-ament-cmake \\\n    ros-${ROS_DISTRO}-rviz2 ros-${ROS_DISTRO}-rqt-graph \\\n    && rm -rf /var/lib/apt/lists/*\nENV CCACHE_DIR=/ccache CC=\"ccache gcc\" CXX=\"ccache g++\"\nCOPY src/ src/\nCOPY ros_entrypoint.sh /ros_entrypoint.sh\nENTRYPOINT [\"/ros_entrypoint.sh\"]\nCMD [\"bash\"]\n\n# Stage 3: Build — compile workspace\nFROM deps AS build\nCOPY src/ src/\nRUN . /opt/ros/${ROS_DISTRO}/setup.sh && \\\n    colcon build \\\n      --cmake-args -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF \\\n      --event-handlers console_direct+ \\\n      --parallel-workers $(nproc)\n\n# Stage 4: Runtime — minimal production image\nFROM ros:${ROS_DISTRO}-ros-core AS runtime\nARG ROS_DISTRO=humble\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    python3-yaml ros-${ROS_DISTRO}-rmw-cyclonedds-cpp \\\n    && rm -rf /var/lib/apt/lists/*\nCOPY --from=build /ros2_ws/install /ros2_ws/install\nRUN groupadd -r rosuser && useradd -r -g rosuser -m -s /bin/bash rosuser\nUSER rosuser\nENV RMW_IMPLEMENTATION=rmw_cyclonedds_cpp\nCOPY ros_entrypoint.sh /ros_entrypoint.sh\nENTRYPOINT [\"/ros_entrypoint.sh\"]\nCMD [\"ros2\", \"launch\", \"my_robot_bringup\", \"robot.launch.py\"]\n```\n\nThe entrypoint script both dev and runtime stages use:\n\n```bash\n#!/bin/bash\nset -e\nsource /opt/ros/${ROS_DISTRO}/setup.bash\nif [ -f /ros2_ws/install/setup.bash ]; then\n    source /ros2_ws/install/setup.bash\nfi\nexec \"$@\"\n```\n\n## Docker Compose for Multi-Container ROS2 Systems\n\n### Basic Multi-Container Setup\n\nEach ROS2 subsystem runs in its own container with process isolation, independent scaling, and per-service resource limits.\n\n```yaml\n# docker-compose.yml\nversion: \"3.8\"\n\nx-ros-common: &ros-common\n  environment:\n    - ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}\n    - RMW_IMPLEMENTATION=rmw_cyclonedds_cpp\n    - CYCLONEDDS_URI=file:///cyclonedds.xml\n  volumes:\n    - ./config/cyclonedds.xml:/cyclonedds.xml:ro\n    - /dev/shm:/dev/shm\n  network_mode: host\n  restart: unless-stopped\n\nservices:\n  rosbridge:\n    <<: *ros-common\n    image: my_robot:latest\n    command: ros2 launch rosbridge_server rosbridge_websocket_launch.xml port:=9090\n\n  perception:\n    <<: *ros-common\n    image: my_robot_perception:latest\n    command: ros2 launch my_robot_perception perception.launch.py\n    deploy:\n      resources:\n        reservations:\n          devices:\n            - driver: nvidia\n              count: 1\n              capabilities: [gpu]\n    devices:\n      - /dev/video0:/dev/video0            # USB camera passthrough\n\n  navigation:\n    <<: *ros-common\n    image: my_robot_navigation:latest\n    command: >\n      ros2 launch my_robot_navigation navigation.launch.py\n        use_sim_time:=false map:=/maps/warehouse.yaml\n    volumes:\n      - ./maps:/maps:ro\n\n  driver:\n    <<: *ros-common\n    image: my_robot_driver:latest\n    command: ros2 launch my_robot_driver driver.launch.py\n    devices:\n      - /dev/ttyUSB0:/dev/ttyUSB0          # Serial motor controller\n      - /dev/ttyACM0:/dev/ttyACM0          # IMU over USB-serial\n    group_add:\n      - dialout\n```\n\n### Service Dependencies with Health Checks\n\n```yaml\nservices:\n  driver:\n    <<: *ros-common\n    image: my_robot_driver:latest\n    healthcheck:\n      test: [\"CMD\", \"bash\", \"-c\",\n             \"source /opt/ros/humble/setup.bash && ros2 topic list | grep -q /joint_states\"]\n      interval: 5s\n      timeout: 10s\n      retries: 5\n      start_period: 15s\n\n  navigation:\n    <<: *ros-common\n    image: my_robot_navigation:latest\n    depends_on:\n      driver:\n        condition: service_healthy         # Wait for driver topics\n\n  perception:\n    <<: *ros-common\n    image: my_robot_perception:latest\n    depends_on:\n      driver:\n        condition: service_healthy         # Camera driver must be ready\n```\n\n### Profiles for Dev vs Deploy\n\n```yaml\nservices:\n  driver:\n    <<: *ros-common\n    image: my_robot_driver:latest\n    command: ros2 launch my_robot_driver driver.launch.py\n\n  rviz:\n    <<: *ros-common\n    profiles: [\"dev\"]\n    image: my_robot:dev\n    command: ros2 run rviz2 rviz2 -d /rviz/config.rviz\n    environment:\n      - DISPLAY=${DISPLAY}\n      - QT_X11_NO_MITSHM=1\n    volumes:\n      - /tmp/.X11-unix:/tmp/.X11-unix:rw\n\n  rosbag_record:\n    <<: *ros-common\n    profiles: [\"dev\"]\n    image: my_robot:dev\n    command: ros2 bag record -a --storage sqlite3 --max-bag-duration 300 -o /bags/session\n    volumes:\n      - ./bags:/bags\n\n  watchdog:\n    <<: *ros-common\n    profiles: [\"deploy\"]\n    image: my_robot:latest\n    command: ros2 launch my_robot_bringup watchdog.launch.py\n    restart: always\n```\n\n```bash\ndocker compose --profile dev up          # Dev tools (rviz, rosbag)\ndocker compose --profile deploy up -d    # Production (watchdog, no GUI)\n```\n\n## DDS Discovery Across Containers\n\n### CycloneDDS XML Config for Unicast Across Containers\n\nWhen containers use bridge networking (no multicast), configure explicit unicast peer lists.\n\n```xml\n<!-- cyclonedds.xml -->\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<CycloneDDS xmlns=\"https://cdds.io/config\">\n  <Domain>\n    <General>\n      <Interfaces>\n        <NetworkInterface autodetermine=\"true\" priority=\"default\"/>\n      </Interfaces>\n      <AllowMulticast>false</AllowMulticast>\n    </General>\n    <Discovery>\n      <!-- Peer list uses docker-compose service names as hostnames -->\n      <Peers>\n        <Peer address=\"perception\"/>\n        <Peer address=\"navigation\"/>\n        <Peer address=\"driver\"/>\n        <Peer address=\"rosbridge\"/>\n      </Peers>\n      <ParticipantIndex>auto</ParticipantIndex>\n      <MaxAutoParticipantIndex>120</MaxAutoParticipantIndex>\n    </Discovery>\n    <Internal>\n      <SocketReceiveBufferSize min=\"10MB\"/>\n    </Internal>\n  </Domain>\n</CycloneDDS>\n```\n\n### FastDDS XML Config\n\n```xml\n<!-- fastdds.xml -->\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<dds xmlns=\"http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles\">\n  <profiles>\n    <participant profile_name=\"docker_participant\" is_default_profile=\"true\">\n      <rtps>\n        <builtin>\n          <discovery_config>\n            <discoveryProtocol>SIMPLE</discoveryProtocol>\n            <leaseDuration><sec>10</sec></leaseDuration>\n          </discovery_config>\n          <initialPeersList>\n            <locator>\n              <udpv4><address>perception</address><port>7412</port></udpv4>\n            </locator>\n            <locator>\n              <udpv4><address>navigation</address><port>7412</port></udpv4>\n            </locator>\n            <locator>\n              <udpv4><address>driver</address><port>7412</port></udpv4>\n            </locator>\n          </initialPeersList>\n        </builtin>\n      </rtps>\n    </participant>\n  </profiles>\n</dds>\n```\n\nMount and activate in compose:\n\n```yaml\n# CycloneDDS\nenvironment:\n  - RMW_IMPLEMENTATION=rmw_cyclonedds_cpp\n  - CYCLONEDDS_URI=file:///cyclonedds.xml\nvolumes:\n  - ./config/cyclonedds.xml:/cyclonedds.xml:ro\n\n# FastDDS\nenvironment:\n  - RMW_IMPLEMENTATION=rmw_fastrtps_cpp\n  - FASTRTPS_DEFAULT_PROFILES_FILE=/fastdds.xml\nvolumes:\n  - ./config/fastdds.xml:/fastdds.xml:ro\n```\n\n### Shared Memory Transport in Docker\n\nDDS shared memory (zero-copy) requires `/dev/shm` sharing between containers. This provides highest throughput for large messages (images, point clouds).\n\n```yaml\nservices:\n  perception:\n    shm_size: \"512m\"                    # Default 64 MB is too small for image topics\n    volumes:\n      - /dev/shm:/dev/shm              # Share host shm for inter-container zero-copy\n```\n\n```xml\n<!-- Enable shared memory in CycloneDDS -->\n<CycloneDDS xmlns=\"https://cdds.io/config\">\n  <Domain>\n    <SharedMemory>\n      <Enable>true</Enable>\n    </SharedMemory>\n  </Domain>\n</CycloneDDS>\n```\n\nConstraints: 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.\n\n## Networking Modes and ROS2 Implications\n\n### Host Networking\n\n```yaml\nservices:\n  my_node:\n    network_mode: host      # Shares host network namespace; DDS multicast works natively\n```\n\n### Bridge Networking (Default)\n\n```yaml\nservices:\n  my_node:\n    networks: [ros_net]\nnetworks:\n  ros_net:\n    driver: bridge          # DDS multicast blocked; requires unicast peer config\n```\n\n### Macvlan Networking\n\n```yaml\nnetworks:\n  ros_macvlan:\n    driver: macvlan\n    driver_opts:\n      parent: eth0\n    ipam:\n      config:\n        - subnet: 192.168.1.0/24\n          gateway: 192.168.1.1\nservices:\n  my_node:\n    networks:\n      ros_macvlan:\n        ipv4_address: 192.168.1.50   # Real LAN IP; DDS multicast works natively\n```\n\n### Decision Table\n\n| Factor              | Host             | Bridge                  | Macvlan               |\n|---------------------|------------------|-------------------------|-----------------------|\n| DDS discovery       | Works natively   | Needs unicast peers     | Works natively        |\n| Network isolation   | None             | Full isolation          | LAN-level isolation   |\n| Port conflicts      | Yes (host ports) | No (mapped ports)       | No (unique IPs)       |\n| Performance         | Native           | Slight overhead         | Near-native           |\n| Multi-host support  | No               | With overlay networks   | Yes (same LAN)        |\n| When to use         | Dev, single host | CI/CD, multi-tenant     | Multi-robot on LAN    |\n\n## GPU Passthrough for Perception\n\n### NVIDIA Container Toolkit Setup\n\n```bash\n# Install NVIDIA Container Toolkit on the host\ncurl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \\\n  | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg\ncurl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \\\n  | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \\\n  | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list\nsudo apt-get update && sudo apt-get install -y nvidia-container-toolkit\nsudo nvidia-ctk runtime configure --runtime=docker\nsudo systemctl restart docker\n```\n\n### Compose Config with deploy.resources\n\n```yaml\nservices:\n  perception:\n    image: my_robot_perception:latest\n    deploy:\n      resources:\n        reservations:\n          devices:\n            - driver: nvidia\n              count: 1                    # Number of GPUs (or \"all\")\n              capabilities: [gpu]\n    environment:\n      - NVIDIA_VISIBLE_DEVICES=all\n      - NVIDIA_DRIVER_CAPABILITIES=compute,utility,video\n    shm_size: \"1g\"                        # Large shm for GPU<->CPU transfers\n```\n\nFor Dockerfiles that need CUDA, start from NVIDIA base and install ROS2 on top:\n\n```dockerfile\nFROM nvidia/cuda:12.2.0-cudnn8-runtime-ubuntu22.04 AS perception-base\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    curl gnupg2 lsb-release \\\n    && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \\\n       -o /usr/share/keyrings/ros-archive-keyring.gpg \\\n    && echo \"deb [arch=$(dpkg --print-architecture) \\\n       signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \\\n       http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main\" \\\n       > /etc/apt/sources.list.d/ros2.list \\\n    && apt-get update && apt-get install -y --no-install-recommends \\\n       ros-humble-ros-base ros-humble-cv-bridge ros-humble-image-transport \\\n    && rm -rf /var/lib/apt/lists/*\n```\n\n### Verification\n\n```bash\ndocker compose exec perception bash -c '\n  nvidia-smi\n  python3 -c \"import torch; print(f\\\"CUDA available: {torch.cuda.is_available()}\\\")\"\n'\n```\n\n## Display Forwarding\n\n### X11 Forwarding\n\n```yaml\nservices:\n  rviz:\n    image: my_robot:dev\n    command: ros2 run rviz2 rviz2\n    environment:\n      - DISPLAY=${DISPLAY:-:0}                   # Forward host display\n      - QT_X11_NO_MITSHM=1                       # Disable MIT-SHM (crashes in Docker)\n    volumes:\n      - /tmp/.X11-unix:/tmp/.X11-unix:rw          # X11 socket\n      - ${HOME}/.Xauthority:/root/.Xauthority:ro  # Auth cookie\n    network_mode: host\n```\n\n```bash\n# Allow local Docker containers to access the X server\nxhost +local:docker\n# More secure variant:\nxhost +SI:localuser:$(whoami)\n```\n\n### Wayland Forwarding\n\n```yaml\nservices:\n  rviz:\n    image: my_robot:dev\n    command: ros2 run rviz2 rviz2\n    environment:\n      - WAYLAND_DISPLAY=${WAYLAND_DISPLAY:-wayland-0}\n      - XDG_RUNTIME_DIR=/run/user/1000\n      - QT_QPA_PLATFORM=wayland\n    volumes:\n      - ${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY}:/run/user/1000/${WAYLAND_DISPLAY}:rw\n```\n\n### Headless Rendering\n\nFor CI/CD or remote machines without a physical display:\n\n```bash\n# Run rviz2 headless with Xvfb for screenshot capture or testing\ndocker run --rm my_robot:dev bash -c '\n  apt-get update && apt-get install -y xvfb mesa-utils &&\n  Xvfb :99 -screen 0 1920x1080x24 &\n  export DISPLAY=:99\n  source /opt/ros/humble/setup.bash\n  ros2 run rviz2 rviz2 -d /config/test.rviz --screenshot /output/frame.png\n'\n```\n\n## Volume Mounts and Workspace Overlays\n\n### Source Mounts for Dev\n\nMount only `src/` during development. Let colcon write `build/`, `install/`, and `log/` inside named volumes to avoid bind mount performance issues.\n\n```yaml\n# BAD: mounting entire workspace — build artifacts on bind mount are slow\n# volumes:\n#   - ./my_ros2_ws:/ros2_ws\n\n# GOOD: mount only source, use named volumes for build artifacts\nservices:\n  dev:\n    image: my_robot:dev\n    volumes:\n      - ./src:/ros2_ws/src:rw                     # Source code (bind mount)\n      - build_vol:/ros2_ws/build                   # Build artifacts (named volume)\n      - install_vol:/ros2_ws/install               # Install space (named volume)\n      - log_vol:/ros2_ws/log                       # Log output (named volume)\n    working_dir: /ros2_ws\n\nvolumes:\n  build_vol:\n  install_vol:\n  log_vol:\n```\n\n### ccache Caching\n\nPersist ccache across container rebuilds for faster C++ compilation:\n\n```yaml\nservices:\n  dev:\n    volumes:\n      - ccache_vol:/ccache\n    environment:\n      - CCACHE_DIR=/ccache\n      - CCACHE_MAXSIZE=2G\n      - CC=ccache gcc\n      - CXX=ccache g++\nvolumes:\n  ccache_vol:\n```\n\n### ROS Workspace Overlay in Docker\n\nKeep upstream packages cached and only rebuild custom packages:\n\n```dockerfile\n# Stage 1: upstream dependencies (rarely changes)\nFROM ros:humble-ros-base AS upstream\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n    ros-humble-nav2-bringup ros-humble-slam-toolbox \\\n    ros-humble-robot-localization \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Stage 2: custom packages overlay on top\nFROM upstream AS workspace\nWORKDIR /ros2_ws\nCOPY src/ src/\nRUN . /opt/ros/humble/setup.sh && colcon build --symlink-install\n# install/setup.bash automatically sources /opt/ros/humble as underlay\n```\n\n## USB Device Passthrough\n\n### Cameras and Serial Devices\n\n```yaml\nservices:\n  camera_driver:\n    image: my_robot_driver:latest\n    devices:\n      - /dev/video0:/dev/video0        # USB camera (V4L2)\n      - /dev/video1:/dev/video1\n    group_add:\n      - video                          # Access /dev/videoN without root\n\n  motor_driver:\n    image: my_robot_driver:latest\n    devices:\n      - /dev/ttyUSB0:/dev/ttyUSB0      # USB-serial motor controller\n      - /dev/ttyACM0:/dev/ttyACM0      # Arduino/Teensy\n    group_add:\n      - dialout                        # Access serial ports without root\n```\n\n### Udev Rules Inside Containers\n\nCreate stable device symlinks on the host so container paths remain consistent regardless of USB enumeration order.\n\n```bash\n# /etc/udev/rules.d/99-robot-devices.rules (host-side)\nSUBSYSTEM==\"tty\", ATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6001\", SYMLINK+=\"robot/motor_controller\"\nSUBSYSTEM==\"tty\", ATTRS{idVendor}==\"10c4\", ATTRS{idProduct}==\"ea60\", SYMLINK+=\"robot/lidar\"\nSUBSYSTEM==\"video4linux\", ATTRS{idVendor}==\"046d\", ATTRS{idProduct}==\"0825\", SYMLINK+=\"robot/camera\"\n```\n\n```bash\nsudo udevadm control --reload-rules && sudo udevadm trigger\n```\n\n```yaml\nservices:\n  driver:\n    devices:\n      - /dev/robot/motor_controller:/dev/ttyMOTOR   # Stable symlink\n      - /dev/robot/lidar:/dev/ttyLIDAR\n      - /dev/robot/camera:/dev/video0\n```\n\n### Dynamic Device Attachment\n\nFor devices plugged in after the container starts:\n\n```yaml\nservices:\n  driver:\n    # Option 1: privileged (use only when necessary)\n    privileged: true\n    volumes:\n      - /dev:/dev\n\n    # Option 2: cgroup device rules (more secure)\n    # device_cgroup_rules:\n    #   - 'c 188:* rmw'                  # USB-serial (major 188)\n    #   - 'c 81:* rmw'                   # Video devices (major 81)\n```\n\n## Dev Container Configuration\n\n```json\n// .devcontainer/devcontainer.json\n{\n  \"name\": \"ROS2 Humble Dev\",\n  \"build\": {\n    \"dockerfile\": \"../Dockerfile\",\n    \"target\": \"dev\",\n    \"args\": { \"ROS_DISTRO\": \"humble\" }\n  },\n  \"runArgs\": [\n    \"--network=host\", \"--ipc=host\", \"--pid=host\",\n    \"--privileged\", \"--gpus\", \"all\",\n    \"-e\", \"DISPLAY=${localEnv:DISPLAY}\",\n    \"-e\", \"QT_X11_NO_MITSHM=1\",\n    \"-v\", \"/tmp/.X11-unix:/tmp/.X11-unix:rw\",\n    \"-v\", \"/dev:/dev\"\n  ],\n  \"workspaceMount\": \"source=${localWorkspaceFolder},target=/ros2_ws/src,type=bind\",\n  \"workspaceFolder\": \"/ros2_ws\",\n  \"mounts\": [\n    \"source=ros2-build-vol,target=/ros2_ws/build,type=volume\",\n    \"source=ros2-install-vol,target=/ros2_ws/install,type=volume\",\n    \"source=ros2-log-vol,target=/ros2_ws/log,type=volume\",\n    \"source=ros2-ccache-vol,target=/ccache,type=volume\"\n  ],\n  \"containerEnv\": {\n    \"ROS_DISTRO\": \"humble\",\n    \"RMW_IMPLEMENTATION\": \"rmw_cyclonedds_cpp\",\n    \"CCACHE_DIR\": \"/ccache\",\n    \"RCUTILS_COLORIZED_OUTPUT\": \"1\"\n  },\n  \"customizations\": {\n    \"vscode\": {\n      \"extensions\": [\n        \"ms-iot.vscode-ros\",\n        \"ms-vscode.cpptools\",\n        \"ms-python.python\",\n        \"ms-vscode.cmake-tools\",\n        \"smilerobotics.urdf\",\n        \"redhat.vscode-xml\",\n        \"redhat.vscode-yaml\"\n      ],\n      \"settings\": {\n        \"ros.distro\": \"humble\",\n        \"python.defaultInterpreterPath\": \"/usr/bin/python3\",\n        \"C_Cpp.default.compileCommands\": \"/ros2_ws/build/compile_commands.json\",\n        \"cmake.configureOnOpen\": false\n      }\n    }\n  },\n  \"postCreateCommand\": \"sudo apt-get update && rosdep update && rosdep install --from-paths src --ignore-src -r -y\",\n  \"remoteUser\": \"rosuser\"\n}\n```\n\n## CI/CD with Docker\n\n### GitHub Actions Workflow\n\n```yaml\n# .github/workflows/ros2-docker-ci.yml\nname: ROS2 Docker CI\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\nenv:\n  REGISTRY: ghcr.io\n  IMAGE_NAME: ${{ github.repository }}\n\njobs:\n  build-and-test:\n    runs-on: ubuntu-22.04\n    strategy:\n      fail-fast: false\n      matrix:\n        ros_distro: [humble, jazzy]\n        include:\n          - ros_distro: humble\n            ubuntu: \"22.04\"\n          - ros_distro: jazzy\n            ubuntu: \"24.04\"\n    steps:\n      - uses: actions/checkout@v4\n      - uses: docker/setup-buildx-action@v3\n      - uses: docker/login-action@v3\n        with:\n          registry: ${{ env.REGISTRY }}\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Cache Docker layers\n        uses: actions/cache@v4\n        with:\n          path: /tmp/.buildx-cache\n          key: ${{ runner.os }}-buildx-${{ matrix.ros_distro }}-${{ hashFiles('src/**/package.xml') }}\n          restore-keys: ${{ runner.os }}-buildx-${{ matrix.ros_distro }}-\n\n      - name: Build and test\n        run: |\n          docker build --target dev \\\n            --build-arg ROS_DISTRO=${{ matrix.ros_distro }} \\\n            -t test-image:${{ matrix.ros_distro }} .\n          docker run --rm test-image:${{ matrix.ros_distro }} bash -c '\n            source /opt/ros/${{ matrix.ros_distro }}/setup.bash &&\n            cd /ros2_ws &&\n            colcon build --cmake-args -DBUILD_TESTING=ON &&\n            colcon test --event-handlers console_direct+ &&\n            colcon test-result --verbose'\n\n      - name: Push runtime image\n        if: github.ref == 'refs/heads/main'\n        uses: docker/build-push-action@v5\n        with:\n          context: .\n          target: runtime\n          build-args: ROS_DISTRO=${{ matrix.ros_distro }}\n          tags: |\n            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.ros_distro }}-latest\n            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.ros_distro }}-${{ github.sha }}\n          push: true\n          cache-from: type=local,src=/tmp/.buildx-cache\n          cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max\n\n      - name: Rotate cache\n        run: rm -rf /tmp/.buildx-cache && mv /tmp/.buildx-cache-new /tmp/.buildx-cache\n```\n\n### Layer Caching\n\nOrder Dockerfile instructions from least-frequently-changed to most-frequently-changed:\n\n```\n1. Base image         (ros:humble-ros-base)     — changes on distro upgrade\n2. System apt packages                           — changes on new dependency\n3. rosdep install     (from package.xml)         — changes on new ROS dep\n4. COPY src/ src/                                — changes on every code edit\n5. colcon build                                  — rebuilds on source change\n```\n\n### Build Matrix Across Distros\n\n```yaml\nstrategy:\n  matrix:\n    ros_distro: [humble, iron, jazzy, rolling]\n    rmw: [rmw_cyclonedds_cpp, rmw_fastrtps_cpp]\n    exclude:\n      - ros_distro: iron           # Iron EOL — skip\n        rmw: rmw_fastrtps_cpp\n```\n\n## Docker ROS2 Anti-Patterns\n\n### 1. Running Everything in One Container\n\n**Problem:** Putting perception, navigation, planning, and drivers in a single container defeats the purpose of containerization. A crash in one subsystem takes down everything.\n\n**Fix:** Split into one service per subsystem. Use docker-compose to orchestrate.\n\n```yaml\n# BAD: monolithic container\nservices:\n  robot:\n    image: my_robot:latest\n    command: ros2 launch my_robot everything.launch.py\n\n# GOOD: one container per subsystem\nservices:\n  perception:\n    image: my_robot_perception:latest\n    command: ros2 launch my_robot_perception perception.launch.py\n  navigation:\n    image: my_robot_navigation:latest\n    command: ros2 launch my_robot_navigation navigation.launch.py\n  driver:\n    image: my_robot_driver:latest\n    command: ros2 launch my_robot_driver driver.launch.py\n```\n\n### 2. Using Bridge Networking Without DDS Config\n\n**Problem:** DDS uses multicast for discovery by default. Docker bridge networks do not forward multicast. Nodes in different containers will not discover each other.\n\n**Fix:** Use `network_mode: host` or configure DDS unicast peers explicitly.\n\n```yaml\n# BAD: bridge network with no DDS config\nservices:\n  node_a:\n    networks: [ros_net]\n  node_b:\n    networks: [ros_net]\n\n# GOOD: host networking (simplest)\nservices:\n  node_a:\n    network_mode: host\n  node_b:\n    network_mode: host\n\n# GOOD: bridge with CycloneDDS unicast peers\nservices:\n  node_a:\n    networks: [ros_net]\n    environment:\n      - RMW_IMPLEMENTATION=rmw_cyclonedds_cpp\n      - CYCLONEDDS_URI=file:///cyclonedds.xml\n    volumes:\n      - ./cyclonedds.xml:/cyclonedds.xml:ro\n```\n\n### 3. Building Packages in the Runtime Image\n\n**Problem:** Installing compilers and build tools in the runtime image bloats it by 1-2 GB and increases attack surface.\n\n**Fix:** Use multi-stage builds. Compile in a build stage, copy only the install space to runtime.\n\n```dockerfile\n# BAD: build tools in runtime image (2.5 GB)\nFROM ros:humble-ros-base\nRUN apt-get update && apt-get install -y build-essential python3-colcon-common-extensions\nCOPY src/ /ros2_ws/src/\nRUN cd /ros2_ws && colcon build\nCMD [\"ros2\", \"launch\", \"my_pkg\", \"bringup.launch.py\"]\n\n# GOOD: multi-stage build (800 MB)\nFROM ros:humble-ros-base AS build\nRUN apt-get update && apt-get install -y python3-colcon-common-extensions\nCOPY src/ /ros2_ws/src/\nRUN cd /ros2_ws && . /opt/ros/humble/setup.sh && colcon build\n\nFROM ros:humble-ros-core AS runtime\nCOPY --from=build /ros2_ws/install /ros2_ws/install\nCMD [\"ros2\", \"launch\", \"my_pkg\", \"bringup.launch.py\"]\n```\n\n### 4. Mounting the Entire Workspace as a Volume\n\n**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.\n\n**Fix:** Mount only `src/` as a bind mount. Use named volumes for build artifacts.\n\n```yaml\n# BAD:\nvolumes:\n  - ./my_ros2_ws:/ros2_ws\n\n# GOOD:\nvolumes:\n  - ./my_ros2_ws/src:/ros2_ws/src\n  - build_vol:/ros2_ws/build\n  - install_vol:/ros2_ws/install\n  - log_vol:/ros2_ws/log\n```\n\n### 5. Running Containers as Root\n\n**Problem:** Running as root inside containers is a security risk. If compromised, the attacker has root access to mounted volumes and devices.\n\n**Fix:** Create a non-root user with appropriate group membership.\n\n```dockerfile\n# BAD:\nFROM ros:humble-ros-base\nCOPY --from=build /ros2_ws/install /ros2_ws/install\nCMD [\"ros2\", \"launch\", \"my_pkg\", \"bringup.launch.py\"]\n\n# GOOD:\nFROM ros:humble-ros-base\nRUN groupadd -r rosuser && \\\n    useradd -r -g rosuser -G video,dialout -m -s /bin/bash rosuser\nCOPY --from=build --chown=rosuser:rosuser /ros2_ws/install /ros2_ws/install\nUSER rosuser\nCMD [\"ros2\", \"launch\", \"my_pkg\", \"bringup.launch.py\"]\n```\n\n### 6. Ignoring Layer Cache Order in Dockerfile\n\n**Problem:** Placing `COPY src/ .` before `rosdep install` means every source change invalidates the dependency cache. All apt packages are re-downloaded on every build.\n\n**Fix:** Copy only `package.xml` files first, install dependencies, then copy source.\n\n```dockerfile\n# BAD: source copy before rosdep\nCOPY src/ /ros2_ws/src/\nRUN rosdep install --from-paths src --ignore-src -r -y\nRUN colcon build\n\n# GOOD: package.xml first, then rosdep, then source\nCOPY src/my_pkg/package.xml /ros2_ws/src/my_pkg/package.xml\nRUN . /opt/ros/humble/setup.sh && rosdep install --from-paths src --ignore-src -r -y\nCOPY src/ /ros2_ws/src/\nRUN . /opt/ros/humble/setup.sh && colcon build\n```\n\n### 7. Hardcoding ROS_DOMAIN_ID\n\n**Problem:** 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.\n\n**Fix:** Use environment variables with defaults. Set domain ID at deploy time.\n\n```yaml\n# BAD:\nenvironment:\n  - ROS_DOMAIN_ID=42\n\n# GOOD:\nenvironment:\n  - ROS_DOMAIN_ID=${ROS_DOMAIN_ID:-0}\n```\n\n```bash\nROS_DOMAIN_ID=1 docker compose up -d    # Robot 1\nROS_DOMAIN_ID=2 docker compose up -d    # Robot 2\n```\n\n### 8. Forgetting to Source setup.bash in Entrypoint\n\n**Problem:** The `CMD` runs `ros2 launch ...` but the shell has not sourced the ROS2 setup files. Fails with `ros2: command not found`.\n\n**Fix:** Use an entrypoint script that sources the underlay and overlay before executing the command.\n\n```dockerfile\n# BAD: no sourcing\nFROM ros:humble-ros-core\nCOPY --from=build /ros2_ws/install /ros2_ws/install\nCMD [\"ros2\", \"launch\", \"my_pkg\", \"bringup.launch.py\"]\n\n# GOOD: entrypoint script handles sourcing\nFROM ros:humble-ros-core\nCOPY --from=build /ros2_ws/install /ros2_ws/install\nCOPY ros_entrypoint.sh /ros_entrypoint.sh\nRUN chmod +x /ros_entrypoint.sh\nENTRYPOINT [\"/ros_entrypoint.sh\"]\nCMD [\"ros2\", \"launch\", \"my_pkg\", \"bringup.launch.py\"]\n```\n\n```bash\n#!/bin/bash\n# ros_entrypoint.sh\nset -e\nsource /opt/ros/${ROS_DISTRO}/setup.bash\nif [ -f /ros2_ws/install/setup.bash ]; then\n    source /ros2_ws/install/setup.bash\nfi\nexec \"$@\"\n```\n\n## Docker ROS2 Deployment Checklist\n\n1. **Multi-stage build** -- Separate dev, build, and runtime stages so production images contain no compilers or build tools\n2. **Non-root user** -- Create a dedicated `rosuser` with only the group memberships needed (video, dialout) instead of privileged mode\n3. **DDS configuration** -- Ship a `cyclonedds.xml` or `fastdds.xml` with explicit peer lists if not using host networking\n4. **Health checks** -- Every service has a health check that verifies the node is running and publishing on expected topics\n5. **Resource limits** -- Set `mem_limit`, `cpus`, and GPU reservations for each service to prevent resource starvation\n6. **Restart policy** -- Use `restart: unless-stopped` for all services and `restart: always` for critical drivers and watchdogs\n7. **Log management** -- Configure Docker logging driver (json-file with max-size/max-file) to prevent disk exhaustion from ROS2 log output\n8. **Environment injection** -- Use `.env` files or orchestrator secrets for `ROS_DOMAIN_ID`, DDS config paths, and device mappings rather than hardcoding\n9. **Shared memory** -- Set `shm_size` to at least 256 MB (512 MB for image topics) and configure DDS shared memory transport for high-bandwidth topics\n10. **Device stability** -- Use udev rules on the host to create stable `/dev/robot/*` symlinks and reference those in compose device mappings\n11. **Image versioning** -- Tag images with both `latest` and a commit SHA or semantic version; never deploy unversioned `latest` to production\n12. **Backup and rollback** -- Keep the previous image version available so a failed deployment can be rolled back by reverting the image tag","tags":["docker","ros2","development","robotics","agent","skills","arpitg1304","agent-skills","ai-coding-assistant","claude-skills"],"capabilities":["skill","source-arpitg1304","skill-docker-ros2-development","topic-agent-skills","topic-ai-coding-assistant","topic-claude-skills","topic-robotics"],"categories":["robotics-agent-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/arpitg1304/robotics-agent-skills/docker-ros2-development","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add arpitg1304/robotics-agent-skills","source_repo":"https://github.com/arpitg1304/robotics-agent-skills","install_from":"skills.sh"}},"qualityScore":"0.544","qualityRationale":"deterministic score 0.54 from registry signals: · indexed on github topic:agent-skills · 189 github stars · SKILL.md body (35,189 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-02T18:54:20.597Z","embedding":null,"createdAt":"2026-04-18T22:05:32.561Z","updatedAt":"2026-05-02T18:54:20.597Z","lastSeenAt":"2026-05-02T18:54:20.597Z","tsv":"'-0':996,1956,3598 '-2':3142 '-22.04':2633 '-50':3304 '/.xauthority':1908 '/24':1537 '/bags':1280,1281 '/bags/session':1278 '/bin/bash':898,930,3424,3717 '/ccache':394,782,2153,2157,2534,2548 '/config/cyclonedds.xml':1006,1377 '/config/fastdds.xml':1393 '/config/test.rviz':2033 '/cyclonedds.xml':1004,1007,1375,1378,3116,3118,3119 '/dev':2419,2420,2489,2490 '/dev/robot':3936 '/dev/robot/camera':2393 '/dev/robot/lidar':2391 '/dev/robot/motor_controller':2387 '/dev/shm':1009,1010,1408,1438,1439,1458 '/dev/ttyacm0':1115,1116,2306,2307 '/dev/ttylidar':2392 '/dev/ttymotor':2388 '/dev/ttyusb0':1110,1111,2299,2300 '/dev/video0':1062,1063,2277,2278,2394 '/dev/video1':2282,2283 '/dev/videon':2288 '/dockerfile':2457 '/etc/apt/sources.list.d/nvidia-container-toolkit.list':1667 '/etc/apt/sources.list.d/ros2.list':1813 '/etc/udev/rules.d/99-robot-devices.rules':2339 '/fastdds.xml':1391,1394 '/joint_states':1153 '/libnvidia-container/gpgkey':1644 '/libnvidia-container/stable/deb/nvidia-container-toolkit.list':1655 '/maps':1090,1091 '/maps/warehouse.yaml':1088 '/max-file':3866 '/my_ros2_ws':2079,3332 '/my_ros2_ws/src':3336 '/opt/ros':693,812,934,2731,3722 '/opt/ros/humble':2257 '/opt/ros/humble/setup.bash':1147,2027 '/opt/ros/humble/setup.sh':465,496,2248,3249,3520,3536 '/output/frame.png':2035 '/package.xml':2690 '/root/.xauthority':1909 '/ros/rosdistro/master/ros.key':1792 '/ros2/ubuntu':1808 '/ros2_ws':453,669,2080,2128,2243,2499,2736,3204,3248,3333 '/ros2_ws/build':2107,2507,3340 '/ros2_ws/build/compile_commands.json':2573 '/ros2_ws/install':565,566,886,887,2114,2516,3263,3264,3343,3396,3397,3432,3433,3677,3678,3699,3700 '/ros2_ws/install/setup.bash':940,943,3728,3731 '/ros2_ws/log':2121,2525,3346 '/ros2_ws/src':2099,2495,3201,3245,3337,3493,3534 '/ros2_ws/src/my_pkg/package.xml':3518 '/ros_entrypoint.sh':581,583,794,796,910,912,3703,3707,3709 '/run/user/1000':1960,1971 '/rviz/config.rviz':1241 '/setup.bash':937,2734,3725 '/setup.sh':696,815 '/src':2098 '/tmp/.buildx-cache':2682,2799,2815,2818 '/tmp/.buildx-cache-new':2806,2817 '/tmp/.x11-unix':1251,1252,1902,1903,2485,2486 '/usr/bin/python3':2571 '/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg':1649,1663 '/usr/share/keyrings/ros-archive-keyring.gpg':1794,1805 '/var/lib/apt/lists':390,451,483,561,667,714,778,882,1844,2230 '0':1885,2021 '04':1764 '0403':2347 '046d':2367 '0825':2370 '1':598,630,1058,1249,1714,1893,2186,2410,2483,2552,2834,2916,3141,3603,3609,3738 '1.1':195,236 '1.2':305 '10':1353,3303,3924 '10c4':2357 '10s':1157 '11':3945 '12':3966 '12.2.0':1759 '120':1347 '15s':1162 '188':2432,2438 '192.168.1.0':1536 '192.168.1.1':1539 '192.168.1.50':1548 '1920x1080x24':2022 '1g':1735 '2':716,2232,2422,2846,3020,3310,3613,3619,3758 '2.2':189,253 '2.5':3173 '2.8':185,272 '20':3313 '22.04':217,235,252,271,2649 '24.04':288,304,2654 '256':3906 '2g':2160 '3':800,2854,3121,3779 '3.5':181 '3.8':981 '300':1276 '4':838,2864,3271,3796 '42':3549,3589 '5':1159,2873,3347,3816 '512':3908 '512m':1427 '5s':1155 '6':3442,3833 '6001':2350 '64':1429 '7':3539,3852 '700':201,218 '7412':1355,1357,1359 '750':289 '8':3620,3875 '800':3218 '81':2440,2445 '9':3897 '9090':1034 '99':2019,2025 'access':1922,2287,2312,3368 'across':29,1323,1330,2140,2882 'action':2601 'actions/cache':2678 'actions/checkout':2657 'activ':1362 'add':1123,2285,2310 'address':1547 'allow':1917 'alway':169,1300,3846 'ament':378,384,755,764 'ament-lint-auto':754 'anti':2914 'anti-pattern':2913 'appropri':3382 'apt':347,351,429,433,467,538,542,634,645,649,698,727,731,858,862,1670,1675,1771,1775,1815,1819,2006,2010,2201,2205,2579,2848,3183,3187,3230,3234,3465 'apt-get':346,350,428,432,466,537,541,644,648,697,726,730,857,861,1669,1674,1770,1774,1814,1818,2005,2009,2200,2204,2578,3182,3186,3229,3233 'arch':1797 'architectur':1801 'arduino/teensy':2308 'arg':501,616,620,820,852,2460,2709,2741,2773 'artifact':2072,2090,2109,3328 'attach':2397 'attack':3146,3365 'attr':2345,2348,2355,2358,2365,2368 'auth':1911 'auto':380,757,1346 'automat':2255 'avail':1863,1865,3975 'avoid':2061 'b':3077,3092 'back':3983 'backup':3967 'bad':2067,2960,3063,3167,3330,3386,3486,3584,3665 'bag':1267,1274 'bandwidth':3922 'base':10,51,123,173,194,205,233,257,302,424,621,628,632,639,1750,1768,1831,2196,2835,2841,3180,3225,3392,3410 'bash':798,929,1144,1301,1632,1846,1851,1916,1986,2003,2338,2373,2728,3599,3716 'basic':954 'best':5 'bind':2062,2074,2103,2497,3293,3299,3321 'bloat':3138 'block':1516 'branch':2611,2616 'bridg':261,1335,1499,1513,1560,1836,3022,3036,3064,3097 'bringup':918,1297,2217 'bringup.launch.py':589,3212,3270,3403,3441,3684,3715 'build':67,117,125,145,157,328,360,403,426,498,503,564,601,609,740,801,807,817,822,885,2053,2071,2089,2105,2108,2130,2250,2455,2504,2626,2699,2704,2708,2738,2772,2875,2880,3122,3132,3153,3157,3168,3192,3206,3217,3227,3251,3262,3287,3307,3327,3338,3395,3428,3473,3508,3538,3676,3698,3742,3745,3756 'build-and-test':2625 'build-arg':2707,2771 'build-essenti':359,739,3191 'buildx':2685,2695 'built':516 'c':1145,1852,1857,2004,2145,2431,2439,2729 'c_cpp.default.compilecommands':2572 'cach':141,413,460,678,2137,2178,2674,2794,2801,2811,2820,3445,3463 'cache-from':2793 'cache-to':2800 'camera':112,1065,1197,2263,2269,2280 'camera/lidar':263 'capabl':1059,1720,1729 'captur':1994 'case':210 'caus':3550 'cc':396,783,2161 'ccach':387,392,397,401,744,780,784,787,2136,2139,2151,2155,2158,2162,2165,2168,2531,2546 'cd':2735,3203,3247 'cgroup':2423,2429 'chang':485,2190,2828,2833,2842,2850,2859,2868,2879,3459 'check':1129,3798,3804 'checklist':3737 'chmod':3705 'choos':170 'chown':3429 'ci':2608 'ci/cd':118,1615,1978,2597 'cloud':1421 'cmake':362,385,500,765,819,2740 'cmake-arg':499,818,2739 'cmake.configureonopen':2574 'cmd':584,797,913,1143,3207,3265,3398,3436,3629,3679,3710 'code':134,526,2102,2871 'colcon':66,143,369,443,497,659,816,2051,2249,2737,2745,2752,2874,3196,3205,3240,3250,3285,3507,3537 'color':2550 'command':1027,1044,1076,1102,1218,1235,1265,1292,1877,1945,2969,2987,3000,3013,3646,3663 'commit':3955 'common':241,310,370,444,660,985,988,1022,1038,1070,1096,1135,1166,1185,1212,1228,1258,1285,3197,3241 'communic':1454 'compil':523,802,2146,3130,3154,3754 'compos':20,72,947,1303,1312,1364,1695,1848,2956,3605,3615,3942 'compromis':3363 'comput':1730 'condit':1175,1194 'config':1327,1350,1520,1534,1696,3026,3069,3889 'configur':87,131,1339,1688,2448,3057,3781,3855,3914 'conflict':1581,3551 'consist':2332 'consol':509,831,2750 'constraint':1452 'contain':24,30,40,76,84,92,151,513,951,957,966,1324,1331,1333,1411,1446,1455,1468,1471,1629,1635,1681,1920,2141,2320,2329,2404,2447,2921,2932,2962,2977,3045,3349,3357,3752 'container':46,2937 'containerenv':2537 'content':208 'context':2768 'control':1114,2305,2376 'cooki':1912 'copi':405,454,461,492,562,579,670,680,683,686,689,789,792,808,883,908,1406,1449,2244,2865,3159,3199,3243,3260,3393,3426,3451,3475,3483,3488,3491,3516,3532,3674,3696,3701 'core':200,215,240,286,309,533,849,3257,3673,3695 'count':1057,1713 'cpp':558,879,907,1001,1372,1386,2545,2896,2899,2910,3113 'cpu':1740 'cpus':3822 'crash':1898,2939 'creat':129,2321,3375,3763,3934 'critic':3848 'cross':3569 'cross-talk':3568 'cs':1811 'ctk':1686 'cuda':1746,1862 'cudnn8':1761 'cudnn8-runtime-ubuntu22':1760 'curl':1640,1650,1783,1788 'custom':2182,2233,2553 'cv':260,1835 'cxx':400,786,2164 'cyclonedd':85,557,878,906,1000,1002,1325,1366,1371,1373,2544,2895,3099,3112,3114 'cyclonedds.xml':3784 'd':1240,1316,2032,3607,3617 'dbuild':825,2742 'dcmake':502,821 'dds':27,80,1321,1401,1495,1514,1552,1562,3025,3028,3058,3068,3780,3888,3915 'dearmor':1647 'deb':1658,1659,1796 'debug':79 'debugg':330 'decis':1556 'dedic':3765 'default':1388,1428,1501,3034,3576 'defeat':2933 'demo':277 'dep':637,642,722,805,2863 'depend':176,416,459,521,631,1126,1172,1191,2188,2853,3462,3481 'deploy':39,150,246,314,1051,1206,1287,1314,1707,3581,3736,3961,3979 'deploy.resources':1698 'design':146 'desktop':179,184,269,342,3298 'desktop-ful':178 'dest':2805 'dev':37,148,322,344,603,607,719,724,924,1204,1230,1234,1260,1264,1305,1307,1612,1876,1944,2002,2044,2092,2096,2149,2446,2454,2459,2706,3744 'dev-vs-deploy':36,147 'devcontain':130 'devcontainer/devcontainer.json':2450 'develop':4,12,53,278,325,717,2049,2613,3556 'devic':109,116,1054,1061,1109,1710,1725,2261,2266,2276,2298,2323,2386,2396,2399,2424,2428,2443,3373,3892,3925,3943 'dialout':1124,2311,3421,3774 'differ':3044 'dir':393,781,1959,1968,2127,2156,2547 'direct':510,832,2751 'disabl':1894 'discov':3048 'discoveri':28,81,1322,1563,3032 'disk':3869 'display':101,1243,1244,1866,1883,1884,1888,1952,1954,1970,1973,1985,2024,2475,2477 'distro':618,625,695,753,760,768,772,814,846,854,875,936,2462,2539,2641,2646,2651,2687,2697,2711,2713,2719,2727,2733,2775,2777,2783,2789,2844,2883,2888,2902,3724 'docker':2,9,19,50,71,122,139,159,600,608,946,1302,1311,1400,1690,1694,1847,1900,1919,1928,1997,2174,2599,2607,2675,2703,2720,2911,2955,3035,3297,3604,3614,3734,3856 'docker-bas':8,49,121 'docker-compos':18,70,2954 'docker-compose.yml':979 'docker-ros2-development':1 'docker/build-push-action':2765 'docker/dockerfile':597 'docker/login-action':2663 'docker/setup-buildx-action':2660 'dockerfil':17,61,319,337,418,527,594,595,1743,1756,2184,2456,2822,3166,3385,3448,3485,3664 'domain':991,994,3542,3547,3565,3578,3587,3593,3596,3601,3611,3886 'download':3470 'dpkg':1798 'driver':1055,1093,1100,1107,1132,1139,1174,1180,1193,1198,1209,1216,1223,1358,1512,1527,1529,1711,1728,2270,2274,2292,2296,2385,2408,2928,3007,3011,3018,3849,3858 'driver.launch.py':1108,1224,3019 'durat':1275 'dynam':2395 'e':932,2474,2478,3720 'ea60':2360 'echo':1795 'edit':2872 'editor':332 'entir':2069,3274 'entrypoint':582,795,911,921,3626,3652,3686,3708 'enumer':2336 'env':391,395,399,779,902,2618,3879 'env.image':2780,2786 'env.registry':2667,2779,2785 'environ':720,989,1242,1367,1381,1722,1882,1950,2154,3108,3573,3585,3591,3876 'eol':2905 'essenti':361,741,3193 'eth0':1532 'event':507,829,2748 'event-handl':506,828,2747 'everi':2870,3457,3472,3799 'everyth':2918,2945 'everything.launch.py':2974 'exclud':2900 'exec':945,1849,3733 'execut':3661 'exhaust':3870 'expect':3814 'explicit':1340,3061,3788 'export':2023 'extens':137,371,445,661,2555,3198,3242 'f':939,1861,3727 'factor':1558 'fail':2636,3643,3978 'fail-fast':2635 'failur':82 'fals':1086,1345,2575,2638 'fast':2637 'fastdd':86,1348,1380 'fastdds.xml':3786 'faster':2144 'fastrtp':1385,1387,2898,2909 'fi':944,3732 'file':410,673,1390,3478,3642,3861,3880 'first':457,3479,3511 'fix':2946,3051,3148,3315,3374,3474,3571,3649 'follow':165 'forget':3621 'forward':97,1867,1869,1886,1937,3040 'found':3648 'frequent':2827,2832 'from-path':472,703,2586,3497,3523 'fssl':1641 'full':180,590,718,1574,3282 'g':402,573,788,894,1664,2166,3417,3419 'gateway':1538 'gb':182,186,190,196,237,254,273,306,3143,3174 'gcc':398,785,2163 'gdb':363,742 'get':348,352,430,434,468,539,543,646,650,699,728,732,859,863,1671,1676,1772,1776,1816,1820,2007,2011,2202,2206,2580,3184,3188,3231,3235 'ghcr.io':2620 'github':2600 'github.actor':2669 'github.ref':2762 'github.repository':2623 'github.sha':2790 'github/workflows/ros2-docker-ci.yml':2604 'gnupg2':1784 'good':2081,2975,3081,3096,3213,3334,3404,3509,3590,3685 'gpg':1646 'gpu':31,88,1060,1624,1721,1739,3824 'gpus':1717,2472 'graph':775 'grep':1151 'group':1122,2284,2309,3383,3770 'groupadd':568,889,3412 'gui':280,1320 'handl':3688 'handler':508,830,2749 'hardcod':3540,3545,3896 'hashfil':2688 'headless':1975,1989 'health':1128,3797,3803 'healthcheck':1141 'healthi':1177,1196 'hierarchi':161,168 'high':3921 'high-bandwidth':3920 'highest':1414 'hit':414 'home':1907 'host':1013,1441,1462,1482,1490,1492,1559,1583,1600,1614,1639,1887,1915,2327,2341,2466,2468,2470,3055,3082,3090,3095,3794,3932 'host-sid':2340 'humbl':213,231,249,268,341,377,383,422,531,555,619,855,1829,1834,1839,2194,2215,2220,2225,2453,2463,2540,2569,2642,2647,2839,2889,3178,3223,3255,3390,3408,3671,3693 'humble-desktop':267,340 'humble-percept':248 'humble-ros-bas':230,421,2193,2838,3177,3222,3389,3407 'humble-ros-cor':212,530,3254,3670,3692 'i/o':3301 'id':992,995,3543,3548,3566,3579,3588,3594,3597,3602,3612,3887 'idproduct':2349,2359,2369 'idvendor':2346,2356,2366 'ignor':477,708,2591,3443,3502,3528 'ignore-src':476,707,2590,3501,3527 'imag':160,164,203,258,622,640,842,1023,1039,1071,1097,1136,1167,1186,1213,1231,1261,1288,1419,1435,1702,1840,1873,1941,2093,2271,2293,2621,2717,2725,2760,2836,2965,2982,2995,3008,3127,3137,3172,3751,3911,3946,3949,3973,3987 'implement':904,998,1369,1383,2542,3110 'implic':1481 'import':1858 'imu':1117 'includ':13,327,2644 'increas':3145 'independ':970 'inject':3877 'insid':2057,2319,3356 'instal':353,357,435,439,471,517,544,548,633,651,655,702,733,737,864,868,1633,1677,1752,1777,1781,1821,1825,2012,2054,2112,2115,2132,2207,2211,2253,2513,2585,2856,3129,3162,3189,3236,3288,3341,3455,3480,3496,3522 'install/setup.bash':2254 'instead':3775 'instruct':2823 'inter':1445 'inter-contain':1444 'interact':335 'interfac':242,311 'interv':1154 'invalid':486,3460 'ip':1551,1590 'ipam':1533 'ipc':1461,1464,1470,2467 'ipv4':1546 'iron':2890,2903,2904 'isol':969,1572,1575,1579 'issu':2065 'jazzi':284,300,315,2643,2652,2891 'jazzy-ros-bas':299 'jazzy-ros-cor':283 'jazzy/noble':297 'job':2624 'json':2449,3860 'json-fil':3859 'keep':2175,3970 'key':2683,2693 'l':1652 'lan':1550,1577,1608,1623 'lan-level':1576 'larg':1417,1736 'latest':615,1026,1043,1075,1101,1140,1171,1190,1217,1291,1706,2275,2297,2784,2968,2986,2999,3012,3952,3963 'launch':223,294,586,762,915,1029,1046,1078,1104,1220,1294,2971,2989,3002,3015,3209,3267,3400,3438,3632,3681,3712 'launch-testing-ament-cmak':761 'layer':140,167,489,2676,2819,3444 'least':2826,3905 'least-frequently-chang':2825 'let':2050 'level':1578 'lidar':113 'limit':977,3818,3821 'lint':379,756 'list':1150,1343,3790 'local':1918,1927,2227,2797,2804 'localenv':2476 'localus':1934 'localworkspacefold':2493 'log':2056,2119,2122,2134,2522,3290,3344,3853,3857,3873 'lsb':1786,1809 'lsb-releas':1785 'm':575,896,3422 'machin':1981 'macos/windows':3296 'macvlan':1521,1526,1528,1545,1561 'main':1812,2612,2617 'major':2437,2444 'manag':107,3854 'manifest':456 'map':1087,1586,3893,3944 'matrix':2639,2881,2886 'matrix.ros':2686,2696,2712,2718,2726,2732,2776,2782,2788 'max':1273,2808,3864 'max-bag-dur':1272 'max-siz':3863 'maxim':412,677 'maxsiz':2159 'mb':202,219,290,1430,3219,3907,3909 'mean':3284,3456 'mem':3820 'membership':3384,3771 'memori':1397,1403,3899,3917 'mesa':2016 'mesa-util':2015 'messag':1418 'minim':224,295,840 'minut':3311,3314 'mit':1896 'mit-shm':1895 'mitshm':1248,1892,2482 'mode':1012,1478,1489,1914,2807,3054,3089,3094,3778 'monolith':2961 'most-frequently-chang':2830 'motor':1113,2291,2304 'mount':1360,2037,2042,2045,2063,2068,2075,2082,2104,2500,3272,3280,3294,3300,3316,3322,3370 'ms-iot.vscode':2556 'ms-python.python':2559 'ms-vscode.cmake':2560 'ms-vscode.cpptools':2558 'multi':15,23,75,155,317,592,950,956,1599,1617,1620,3151,3215,3740 'multi-contain':22,74,949,955 'multi-host':1598 'multi-robot':1619 'multi-stag':14,154,316,591,3150,3214,3739 'multi-ten':1616 'multicast':1338,1496,1515,1553,3030,3041 'multipl':3553 'must':1199,1456 'mv':2816 'name':2058,2086,2110,2117,2124,2451,2605,2622,2673,2698,2757,2781,2787,2809,3324 'namespac':1494 'nativ':1498,1555,1565,1570,1592,1597 'nav2':2216 'navig':1067,1074,1081,1163,1170,1356,2925,2994,2998,3005 'navigation.launch.py':1082,3006 'near':1596 'near-nat':1595 'necessari':2415 'need':1566,1745,3772 'net':1508,1511,3075,3080,3107 'network':1011,1336,1477,1483,1488,1493,1500,1506,1509,1522,1524,1543,1571,1605,1913,2465,3023,3037,3053,3065,3073,3078,3083,3088,3093,3105,3559,3795 'never':3960 'new':2852,2861 'no-install-recommend':355,437,546,653,735,866,1779,1823,2209 'node':96,228,1487,1505,1542,3042,3071,3076,3086,3091,3103,3808 'non':3378,3760 'non-root':3377,3759 'none':1573 'nproc':836 'number':1715 'nvidia':91,1056,1628,1634,1680,1685,1712,1723,1727,1749,1854 'nvidia-container-toolkit':1679 'nvidia-ctk':1684 'nvidia-smi':1853 'nvidia.github.io':1643,1654 'nvidia.github.io/libnvidia-container/gpgkey':1642 'nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list':1653 'nvidia/cuda':1758 'o':1277,1648,1793 'offici':162 'one':1467,2920,2941,2949,2976 'opt':1530 'optim':138 'option':2409,2421 'orchestr':2958,3882 'order':2337,2821,3446 'os':206 'osrf':163 'other':1473 'output':2123,2551,3874 'overhead':1594 'overlay':1604,2040,2172,2235,3659 'packag':455,2177,2183,2234,2849,3123,3466 'package.xml':409,672,2858,3477,3510 'packages.ros.org':1807 'packages.ros.org/ros2/ubuntu':1806 'parallel':834 'parallel-work':833 'parent':1531 'passthrough':32,89,110,1066,1625,2262 'password':2670 'path':474,705,2330,2588,2681,3499,3525,3890 'pattern':41,2915 'pcl':262 'peer':1342,1519,1568,3060,3101,3789 'per':974,2951,2978 'per-servic':973 'percept':34,95,188,250,264,274,1035,1042,1049,1182,1189,1354,1424,1627,1701,1705,1767,1850,2924,2981,2985,2992 'perception-bas':1766 'perception.launch.py':1050,2993 'perform':1591,2064 'period':1161 'persist':2138 'physic':1984 'pid':2469 'pip':366,747 'pipelin':119,265 'pkg':588,3211,3269,3402,3440,3683,3714 'place':3450 'plan':2926 'platform':1963 'plug':2400 'point':1420 'polici':3835 'port':1033,1580,1584,1587,2314 'postcreatecommand':2576 'practic':6 'prevent':3830,3868 'previous':3972 'print':1800,1860 'print-architectur':1799 'privileg':2411,2416,2471,3777 'problem':2922,3027,3128,3279,3352,3449,3544,3627 'process':968 'product':245,313,841,1317,3750,3965 'profil':1202,1229,1259,1286,1304,1313,1389 'provid':1413 'publish':3812 'pull':2614 'purpos':2935 'push':2610,2758,2791 'put':2923 'pytest':386,750 'python.defaultinterpreterpath':2570 'python3':365,368,373,442,447,551,658,663,746,749,871,1856,3195,3239 'python3-colcon-common-extensions':367,441,657,3194,3238 'python3-pip':364,745 'python3-pytest':748 'python3-rosdep':372,446,662 'python3-yaml':550,870 'q':1152 'qpa':1962 'qt':1245,1889,1961,2479 'r':479,569,572,710,890,893,2593,3413,3416,3504,3530 'rare':2189 'rather':3894 'raw.githubusercontent.com':1791 'raw.githubusercontent.com/ros/rosdistro/master/ros.key':1790 'rclcpp':220,291 'rclpi':221,292 'rcutil':2549 're':3469 're-download':3468 'readi':1201 'real':1549 'rebuild':2142,2181,2876 'recommend':358,440,549,656,738,869,1782,1826,2212 'record':1255,1268 'redhat.vscode':2563,2565 'refer':3939 'refs/heads/main':2763 'regardless':2333 'registri':2619,2666 'releas':505,824,1787,1810 'reload':2378 'reload-rul':2377 'remain':2331 'remot':1980 'remoteus':2595 'render':1976 'request':2615 'requir':1407,1517 'reserv':1053,1709,3825 'resolut':417,676 'resourc':976,1052,1708,3817,3831 'restart':1014,1299,1693,3834,3837,3845 'restor':2692 'restore-key':2691 'result':2755 'retri':1158 'reus':679 'revert':3985 'rf':389,450,482,560,666,713,777,881,1843,2229,2814 'risk':3361 'rm':388,449,481,559,665,712,776,880,1842,1999,2228,2722,2813 'rmw':556,877,903,905,997,999,1368,1370,1382,1384,2433,2441,2541,2543,2893,2894,2897,2907,2908,3109,3111 'rmw-cyclonedds-cpp':876 'ro':1008,1092,1379,1395,1910,3120 'robot':25,77,606,614,917,1025,1041,1048,1073,1080,1099,1106,1138,1169,1188,1215,1222,1233,1263,1290,1296,1621,1704,1875,1943,2001,2095,2226,2273,2295,2964,2967,2973,2984,2991,2997,3004,3010,3017,3554,3561,3608,3618 'robot.launch.py':919 'robot/camera':2372 'robot/lidar':2362 'robot/motor_controller':2352 'roll':2892,3982 'rollback':3969 'root':2290,2316,3351,3355,3367,3379,3761 'ros':177,183,187,191,193,197,199,211,214,229,232,239,247,256,266,282,285,298,301,308,339,376,382,420,423,529,532,554,617,623,624,627,694,751,752,758,759,766,767,770,771,813,844,845,848,853,873,874,935,984,987,990,993,1021,1037,1069,1095,1134,1165,1184,1211,1227,1257,1284,1507,1510,1525,1544,1828,1830,1833,1838,2170,2192,2195,2214,2219,2224,2461,2538,2557,2640,2645,2650,2710,2774,2837,2840,2862,2887,2901,3074,3079,3106,3176,3179,3221,3224,3253,3256,3388,3391,3406,3409,3541,3546,3586,3592,3595,3600,3610,3669,3672,3691,3694,3723,3885 'ros-bas':192,255,626 'ros-common':986,1020,1036,1068,1094,1133,1164,1183,1210,1226,1256,1283 'ros-cor':198,238,307,847 'ros-humble-ament-cmake-pytest':381 'ros-humble-ament-lint-auto':375 'ros-humble-cv-bridg':1832 'ros-humble-image-transport':1837 'ros-humble-nav2-bringup':2213 'ros-humble-rmw-cyclonedds-cpp':553 'ros-humble-robot-loc':2223 'ros-humble-ros-bas':1827 'ros-humble-slam-toolbox':2218 'ros.distro':2568 'ros2':3,11,47,52,63,124,136,158,321,585,914,952,960,1028,1045,1077,1103,1148,1219,1236,1266,1293,1480,1753,1878,1946,2028,2452,2503,2512,2521,2530,2606,2912,2970,2988,3001,3014,3208,3266,3399,3437,3631,3640,3645,3680,3711,3735,3872 'ros2-build-vol':2502 'ros2-ccache-vol':2529 'ros2-install-vol':2511 'ros2-log-vol':2520 'ros_entrypoint.sh':580,793,909,3702,3718 'rosbag':1254,1310 'rosbag2':243,312 'rosbridg':1019,1030 'rosbridge_websocket_launch.xml':1032 'rosdep':374,448,470,636,664,675,701,2582,2584,2855,3454,3490,3495,3513,3521 'rosout':222,293 'rosus':570,574,576,578,891,895,899,901,2596,3414,3418,3425,3430,3431,3435,3766 'rotat':2810 'rqt':105,276,774 'rqt-graph':773 'rule':2318,2379,2425,2430,3929 'run':345,427,464,495,536,567,643,692,725,811,856,888,962,1237,1769,1879,1947,1987,1998,2029,2199,2247,2630,2702,2721,2812,2917,3181,3202,3228,3246,3348,3353,3411,3494,3506,3519,3535,3630,3704,3810 'runarg':2464 'runner':128 'runner.os':2684,2694 'runs-on':2629 'runtim':225,296,511,520,535,611,839,851,926,1687,1689,1762,1958,1967,2759,2770,3126,3136,3165,3171,3259,3747 'rviz':1225,1309,1872,1940 'rviz2':103,275,769,1238,1239,1880,1881,1948,1949,1988,2030,2031 'rw':1253,1904,1974,2100,2487 'satisfi':175 'scale':971 'scope':1475 'screen':2020 'screenshot':1993,2034 'script':922,3653,3687 'secret':3883 'secrets.github':2671 'secur':1930,2427,3360 'sed':1656 'semant':3958 'separ':3743 'serial':115,1112,1121,2265,2303,2313,2436 'server':1031,1925 'servic':975,1018,1125,1131,1176,1195,1208,1423,1485,1503,1540,1700,1871,1939,2091,2148,2268,2384,2407,2950,2963,2980,3070,3085,3102,3800,3828,3843 'set':68,931,2567,3577,3719,3819,3900 'setup':958,1631,3641 'setup.bash':3624 'sha':3956 'share':1396,1402,1409,1440,1457,1476,1491,3557,3898,3916 'shareabl':1465 'shell':3635 'ship':3782 'shm':1425,1442,1733,1737,1897,3901 'si':1933 'side':2342 'sign':1661,1803 'signed-bi':1660,1802 'sim':1084 'simpl':1352 'simplest':3084 'singl':227,1613,2931 'size':207,1426,1734,3865,3902 'skill':44,54,59 'skill-docker-ros2-development' 'skip':2906 'slam':2221 'slight':1593 'slow':2077 'slower':3306 'small':1433 'smallest':172 'smi':1855 'smilerobotics.urdf':2562 'socket':1906 'sourc':484,525,933,942,1146,2026,2041,2084,2101,2256,2492,2501,2510,2519,2528,2730,2878,3458,3484,3487,3515,3623,3638,3655,3667,3689,3721,3730 'source-arpitg1304' 'space':518,2116,3163 'split':2947 'sqlite3':1271 'src':407,475,478,493,494,706,709,790,791,809,810,2047,2245,2246,2589,2592,2689,2798,2866,2867,3200,3244,3318,3452,3492,3500,3503,3526,3529,3533 'src/my_pkg/package.xml':462,463,3517 'src/my_robot_bringup/package.xml':681,682 'src/my_robot_msgs/package.xml':687,688 'src/my_robot_navigation/package.xml':690,691 'src/my_robot_perception/package.xml':684,685 'ssl':1789 'stabil':3926 'stabl':2322,2389,3935 'stage':16,156,318,323,326,404,512,593,629,715,799,837,927,2185,2231,3152,3158,3216,3741,3748 'start':1160,1747,2405 'starvat':3832 'step':2655 'stop':1017,3840 'storag':1270 'strategi':152,2634,2885 'subnet':1535 'subsystem':961,2343,2353,2363,2942,2952,2979 'sudo':1645,1665,1668,1673,1683,1691,2374,2380,2577 'support':333,1601 'surfac':3147 'symlink':2252,2324,2351,2361,2371,2390,3937 'symlink-instal':2251 'syntax':596 'system':26,78,953,2847 'systemctl':1692 'tabl':1557 'tag':204,2778,3948,3988 'take':2943,3309,3312 'talk':3570 'target':602,610,2458,2494,2506,2515,2524,2533,2705,2769 'tee':1666 'tenant':1618 'test':127,763,826,1142,1996,2628,2701,2716,2724,2743,2746,2754 'test-imag':2715,2723 'test-result':2753 'throughput':1415 'time':1085,3582 'timeout':1156 'token':2672 'tool':106,281,329,1308,2561,3133,3169,3757 'toolbox':2222 'toolkit':93,1630,1636,1682 'top':1755,2237 'topic':1149,1181,1436,3815,3912,3923 'topic-agent-skills' 'topic-ai-coding-assistant' 'topic-claude-skills' 'topic-robotics' 'torch':1859 'torch.cuda.is':1864 'transfer':1741 'transport':259,1398,1841,3918 'trigger':2382 'true':1451,2417,2792 'tti':2344,2354 'two':3560 'type':504,823,2496,2508,2517,2526,2535,2796,2803 'ubuntu':216,234,251,270,287,303,2632,2648,2653 'ubuntu22':1763 'udev':2317,3928 'udevadm':2375,2381 'underlay':2259,3657 'unicast':1329,1341,1518,1567,3059,3100 'uniqu':1589 'unless':1016,3839 'unless-stop':1015,3838 'unvers':3962 'updat':349,431,469,540,647,700,729,860,1672,1773,1817,2008,2203,2581,2583,3185,3232 'upgrad':2845 'upstream':2176,2187,2198,2239 'uri':1003,1374,3115 'usag':599 'usb':108,1064,1120,2260,2279,2302,2335,2435 'usb-seri':1119,2301,2434 'use':42,57,209,336,928,1083,1334,1460,1463,1611,2085,2412,2656,2659,2662,2677,2764,2953,3021,3029,3052,3149,3323,3572,3650,3793,3836,3878,3927 'user':577,900,3380,3434,3762 'useradd':571,892,3415 'usernam':2668 'util':1731,2017 'v':2484,2488 'v3':2661,2664 'v4':2658,2679 'v4l2':2281 'v5':2766 'valgrind':743 'variabl':3574 'variant':1931 'verbos':2756 'verif':1845 'verifi':3806 'version':980,3947,3959,3974 'video':1732,2286,2442,3420,3773 'video4linux':2364 'visibl':1724 'vol':2106,2113,2120,2131,2133,2135,2152,2169,2505,2514,2523,2532,3339,3342,3345 'volum':1005,1089,1250,1279,1376,1392,1437,1901,1965,2036,2059,2078,2087,2097,2111,2118,2125,2129,2150,2167,2418,2509,2518,2527,2536,3117,3278,3325,3331,3335,3371 'vs':38,133,149,1205 'vscode':2554 'w':48 'wait':1178 'watchdog':1282,1318,3851 'watchdog.launch.py':1298 'wayland':100,1936,1951,1953,1955,1964,1969,1972 'whoami':1935 'without':1982,2289,2315,3024 'work':1497,1554,1564,1569,2126 'workdir':452,668,2242 'worker':835 'workflow':2602 'workspac':64,144,803,2039,2070,2171,2241,3275,3283 'workspacefold':2498 'workspacemount':2491 'write':60,2052,3286 'x':983,1924,3305,3706 'x-ros-common':982 'x11':98,1246,1868,1890,1905,2480 'xdg':1957,1966 'xhost':1926,1932 'xml':1326,1344,1349,1351,1450,2564 'xvfb':1991,2014,2018 'y':354,436,480,545,652,711,734,865,1678,1778,1822,2013,2208,2594,3190,3237,3505,3531 'yaml':552,872,978,1130,1207,1365,1422,1484,1502,1523,1699,1870,1938,2066,2147,2267,2383,2406,2566,2603,2884,2959,3062,3329,3583 'yes':1582,1606 'zero':1405,1448 'zero-copi':1404,1447","prices":[{"id":"9d2a7f5c-a08a-4d59-9056-25366b6e4aaa","listingId":"a3416e77-997c-47c7-a2b4-f39d3d9ba1b9","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"arpitg1304","category":"robotics-agent-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:05:32.561Z"}],"sources":[{"listingId":"a3416e77-997c-47c7-a2b4-f39d3d9ba1b9","source":"github","sourceId":"arpitg1304/robotics-agent-skills/docker-ros2-development","sourceUrl":"https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development","isPrimary":false,"firstSeenAt":"2026-04-18T22:05:32.561Z","lastSeenAt":"2026-05-02T18:54:20.597Z"}],"details":{"listingId":"a3416e77-997c-47c7-a2b4-f39d3d9ba1b9","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"arpitg1304","slug":"docker-ros2-development","github":{"repo":"arpitg1304/robotics-agent-skills","stars":189,"topics":["agent-skills","ai-coding-assistant","claude-skills","robotics"],"license":"apache-2.0","html_url":"https://github.com/arpitg1304/robotics-agent-skills","pushed_at":"2026-03-25T03:44:12Z","description":"Agent skills that make AI coding assistants write production-grade robotics software. ROS1, ROS2, design patterns, SOLID principles, and testing — for Claude Code, Cursor, Copilot, and any SKILL.md-compatible agent.","skill_md_sha":"4ad0628a8942cc61e1ccc8c0b59600224909a6b9","skill_md_path":"skills/docker-ros2-development/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/arpitg1304/robotics-agent-skills/tree/main/skills/docker-ros2-development"},"layout":"multi","source":"github","category":"robotics-agent-skills","frontmatter":{"name":"docker-ros2-development","description":"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 passthrough for cameras and serial devices. Trigger whenever the user mentions Docker with ROS2, docker-compose for robots, Dockerfile for colcon workspaces, container networking for DDS, GPU containers for perception, devcontainer for ROS2, multi-stage builds for ROS2, or deploying ROS2 in containers. Also trigger for CI/CD with Docker-based ROS2 builds, CycloneDDS or FastDDS configuration in containers, shared memory in Docker, or X11 forwarding for rviz2. Covers Humble, Iron, Jazzy, and Rolling distributions across Ubuntu 22.04 and 24.04 base images."},"skills_sh_url":"https://skills.sh/arpitg1304/robotics-agent-skills/docker-ros2-development"},"updatedAt":"2026-05-02T18:54:20.597Z"}}