# syntax=docker/dockerfile:1 # ── Stage 1: build ──────────────────────────────────────────────────────────── FROM ros:kilted AS builder RUN apt-get update && apt-get install -y --no-install-recommends \ python3-colcon-common-extensions \ python3-pip \ ros-${ROS_DISTRO}-ament-cmake-python \ && rm -rf /var/lib/apt/lists/* WORKDIR /ws # Install the vendored Raspbot hardware library COPY raspbot_v2_interface/ raspbot_v2_interface/ # PEP 668: newer Debian/Ubuntu marks the system Python as externally managed and blocks pip # by default. --break-system-packages overrides this; safe here as the container is isolated. RUN pip3 install --no-cache-dir --break-system-packages ./raspbot_v2_interface # Copy the ROS package into the standard colcon src/ layout and build it COPY package.xml setup.py setup.cfg CMakeLists.txt src/my_robot/ COPY my_robot/ src/my_robot/my_robot/ RUN . /opt/ros/${ROS_DISTRO}/setup.sh && \ colcon build --packages-select my_robot # ── Stage 2: runtime ────────────────────────────────────────────────────────── FROM ros:kilted-ros-core RUN apt-get update && apt-get install -y --no-install-recommends \ ros-${ROS_DISTRO}-rclpy \ ros-${ROS_DISTRO}-geometry-msgs \ ros-${ROS_DISTRO}-std-msgs \ && rm -rf /var/lib/apt/lists/* # Bring across the installed Raspbot library and the built ROS overlay COPY --from=builder /usr/local/lib /usr/local/lib COPY --from=builder /ws/install /ws/install # Source both ROS base and the workspace overlay on every shell/exec RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /etc/bash.bashrc && \ echo "source /ws/install/setup.bash" >> /etc/bash.bashrc COPY docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["ros2", "run", "my_robot", "motor_controller"]