Everything we've built for ARCHO so far has been tested on one specific development system with a specific version of Jazzy installed. But when a colleague wants to run the same project, or you want to deploy the same code to ten different ARCHO units, a classic problem appears.
"It works on my laptop" but "it's broken on your system" โ because the ROS version, the package versions, or even the operating system version differ.
Docker means packaging the project's entire software environment โ the ROS version, dependencies, packages, and environment variables โ into a reproducible Container. With Docker, ARCHO's runtime environment is exactly the same, whether it runs on your laptop, on a colleague's computer, or on the robot itself.
# Dockerfile
FROM ros:jazzy-ros-base
SHELL ["/bin/bash", "-c"]
RUN apt-get update && apt-get install -y \
python3-colcon-common-extensions \
ros-jazzy-navigation2 \
ros-jazzy-nav2-bringup \
ros-jazzy-slam-toolbox \
ros-jazzy-robot-localization \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /archo_ws
COPY src /archo_ws/src
RUN source /opt/ros/jazzy/setup.bash && \
colcon build --symlink-install
COPY docker/entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["bash"]
#!/bin/bash
# docker/entrypoint.sh
set -e
source /opt/ros/jazzy/setup.bash
if [ -f /archo_ws/install/setup.bash ]; then
source /archo_ws/install/setup.bash
fi
exec "$@"
RViz and Gazebo (Chapters 6 and 7) need a real display, and Containers by default have no graphical interface at all. A few common approaches solve this problem:
| Approach | Best for |
|---|---|
| X11 Forwarding | Linux, fast for local development |
| Wayland Forwarding | Newer Linux distributions |
| VNC | Remote access or non-Linux operating systems |
| Gazebo on the Host, Nodes inside the Container | Gradual, simplest starting setup |
The best starting point is to run Gazebo and RViz directly on Ubuntu and keep only the processing Nodes (Nav2, SLAM, controllers) inside Docker. Once this combination is stable, you can gradually containerize the whole system โ for example with a Dev Container in VS Code.
# docker-compose.yml
services:
archo:
build: .
network_mode: host
privileged: true
volumes:
- /dev:/dev
environment:
- ROS_DOMAIN_ID=20
This setting greatly simplifies DDS communication between Nodes (because the Containers sit directly on the Host network), but from a security and environment-isolation standpoint it must be used deliberately โ especially on a robot that is also connected to an external network.
Docker doesn't simulate the robot itself; it makes the robot's software environment reproducible, deliverable, and deployable.
| Meaning | |
|---|---|
| CI (Continuous Integration) | Every time code changes: Build, Test, and Lint run automatically |
| CD (Continuous Delivery/Deployment) | Once CI passes: Package, Deploy, Release |
On a professional robot, testing isn't done just before final delivery; it is repeated automatically with every code change.
# .github/workflows/ros2-ci.yml
name: ROS 2 CI
on:
push:
pull_request:
jobs:
build-and-test:
runs-on: ubuntu-24.04
container:
image: ros:jazzy-ros-base
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
shell: bash
run: |
apt-get update
apt-get install -y python3-colcon-common-extensions
rosdep update
rosdep install \
--from-paths src \
--ignore-src \
-r -y
- name: Build
shell: bash
run: |
source /opt/ros/jazzy/setup.bash
colcon build --event-handlers console_direct+
- name: Test
shell: bash
run: |
source /opt/ros/jazzy/setup.bash
source install/setup.bash
colcon test
- name: Test results
shell: bash
run: |
colcon test-result --verbose
Note: the YAML file above only implements the Build and Test stages; the Lint and Security Scan stages are shown in this diagram as part of a complete, realistic Quality Gate, and adding them (for example with ament_lint or security-scanning tools) is left as an exercise.
| Test type | What it checks |
|---|---|
| Unit Test | A single small, isolated function or class |
| Integration Test | Correct communication between several Nodes |
| Launch Test | Does the whole system launch without errors? |
| Simulation Test | Does ARCHO correctly follow a specified path in Gazebo? |
| Regression Test | Did a new change break a capability that used to work? |
ARCHO's code is now packaged into a reproducible Container, and every code change is automatically built, tested, and checked before it is allowed to merge. That means delivering a new software version to a real ARCHO unit is no longer a manual, error-prone process from here on.
ARCHO project now has a complete Dockerfile and Docker Compose setup for packaging its software, and every new commit is automatically built and tested in GitHub Actions.
In Chapter Sixteen we step out of the software world and turn to ARCHO's own computing hardware: Jetson, Raspberry Pi, and ESP32 โ and which kind of processing each one is suited for.
network_mode: host carelessly, without regard to security.