Lab 2: ROS2 in Docker on Mini Pupper
Introduction
In this lab, you will learn how to run ROS2 nodes inside Docker containers on Mini Pupper. Docker provides a consistent environment where dependencies remain stable regardless of system updates.
Prerequisites
- Completed Lab 1 (Docker Fundamentals)
- Mini Pupper with Ubuntu installed
- Docker installed on Mini Pupper
- AWS Cloud9 instance (for building ARM images)
Part 1: Why ROS2 in Docker?
Docker Instance as an OS Instance
A Docker container is essentially a lightweight OS instance where you can:
- Install ROS2 and all dependencies
- Mount host files into the container
- Run ROS2 nodes from within the container
Advantages
- No software update worries: Container environment stays consistent
- Dependency consistency: All dependencies are locked in the image
- Easy deployment: Ship the entire environment as a single image
Disadvantages
- Need to compile/build the image
- Docker images can be large files
- Slight performance overhead
Part 2: Setup for ARM Cross-Compilation
Since Mini Pupper uses ARM architecture, you may need to build images on an x86 machine with ARM emulation.
On x86 Machine (AWS Cloud9)
Install QEMU for ARM emulation:
sudo apt-get update && sudo apt-get install -y --no-install-recommends \
qemu-user-static \
binfmt-support \
docker-compose
# Enable ARM emulation
sudo update-binfmts --enable qemu-arm
sudo update-binfmts --display qemu-arm
# Setup multiarch support
sudo apt-get install -y qemu-user-static binfmt-support
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
Part 3: Build ROS2 Music Docker Image
Clone the Repository
On your AWS Cloud9 instance:
git clone -b ros2-dev-music https://github.com/lbaitemple/mini_pupper_ros_aws/
Build the Docker Image
cd mini_pupper_ros_aws/
docker-compose build
Export the Image
Find and export the Docker image as a tar file:
docker save -o image_name.tar ros-humble-greengrass-music-minipupper:latest
Part 4: Setup on Mini Pupper
Prepare Mini Pupper
Create the required directories on Mini Pupper:
mkdir -p ~/minipupper/playlist
mkdir -p ~/tmp
Install Latest Docker Compose
Ensure you have the latest docker-compose installed:
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo rm -f /usr/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# Verify installation
docker-compose --version
Load the Docker Image
Download and load the pre-built image:
cd ~/tmp
wget https://github.com/lbaitemple/mini_pupper_ros_aws/releases/download/image/image_name.tar
docker load -i image_name.tar
Part 5: Configure Docker Compose
Download docker-compose.yml
cd ~/tmp
wget https://raw.githubusercontent.com/lbaitemple/mini_pupper_ros_aws/refs/heads/ros2-dev-music/greengrass/docker-compose.yaml
Understanding the Configuration
The docker-compose.yml mounts necessary devices and volumes:
pupper-robot:
image: ros-humble-greengrass-music-minipupper:latest
devices:
- "/dev/snd:/dev/snd" # Pass the sound device from the host to the container
volumes:
- /tmp/esp32-proxy.socket:/tmp/esp32-proxy.socket
- /home/ubuntu/minipupper/playlist:/app/audio
| Configuration | Purpose |
|---|---|
devices: /dev/snd | Allows container to access audio hardware |
volumes: esp32-proxy.socket | Communication with ESP32 microcontroller |
volumes: playlist:/app/audio | Mount audio files from host |
Part 6: Run ROS2 Container
Start the Container
cd ~/tmp
docker-compose --profile pupper-robot up -d
Enter the Container
Use docker exec to enter the running container:
# Find the container ID
docker ps
# Enter the container
docker exec -it [container_id] /robot-entrypoint.sh /bin/bash
Replace [container_id] with the actual container ID from docker ps.
Part 7: Control Music with ROS2
Once inside the Docker container, you can control the music player using ROS2 services and topics.
Using ROS2 Services
# Source the ROS2 workspace
source /opt/ros_demos/setup.bash
# Play music (starts at 3 seconds into the track)
ros2 service call /play_music mini_pupper_interfaces/srv/PlayMusic "{file_name: 'robot0.mp3', start_second: 3}"
# Stop music
ros2 service call /stop_music mini_pupper_interfaces/srv/StopMusic
Using ROS2 Topics
# Source the workspace
source /opt/ros_demos/setup.bash
# Play music via topic
ros2 topic pub --once /music_file std_msgs/msg/String "data: 'robot0.mp3'"
# Stop music via topic
ros2 topic pub --once /music_file std_msgs/msg/String "data: 'stop'"
Part 8: Managing the Container
View Container Logs
docker-compose logs pupper-robot
Stop the Container
docker-compose down
Restart the Container
docker-compose --profile pupper-robot up -d
Part 9: Adding Your Own Music
Upload Music Files
Copy your MP3 files to the playlist directory on Mini Pupper:
# From your local machine
scp your_music.mp3 ubuntu@<minipupper_ip>:~/minipupper/playlist/
# Or download directly on Mini Pupper
cd ~/minipupper/playlist
wget <url_to_your_music>
Play Your Music
Inside the Docker container:
source /opt/ros_demos/setup.bash
ros2 topic pub --once /music_file std_msgs/msg/String "data: 'your_music.mp3'"
Summary
In this lab, you learned:
- Why Docker is useful for ROS2 development
- How to set up ARM cross-compilation for Mini Pupper
- How to build and export Docker images
- How to load and run Docker containers on Mini Pupper
- How to use
docker execto enter running containers - How to control ROS2 nodes (music player) inside Docker
- How to manage Docker containers with docker-compose
Architecture Overview
┌─────────────────────────────────────────────────────────────────────┐
│ Mini Pupper (ARM) │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ Docker Container │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ ROS2 Humble │ │ Music Player │ │ │
│ │ │ Environment │ │ Node │ │ │
│ │ └─────────────────┘ └─────────────────┘ │ │
│ │ │ │
│ │ Mounted: /app/audio ←→ ~/minipupper/playlist │ │
│ │ Device: /dev/snd (audio hardware) │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ Host: Ubuntu on Raspberry Pi │
└─────────────────────────────────────────────────────────────────────┘