A containerized ROS2 development environment using Dev Containers for consistent, reproducible builds across different systems.
- Overview
- Prerequisites
- Quick Start
- Development Setup
- Building and Running
- Project Structure
- Common Commands
- GUI Applications
- GPU Support
- Troubleshooting
- C++ Development Tools
- Resources
This workspace is configured for ROS2 development using Docker Dev Containers. The setup provides:
- Containerized Environment: Isolated development environment with consistent ROS2 distribution (Jazzy)
- VS Code Integration: Seamless development experience with VS Code Dev Containers extension
- GPU Support: NVIDIA GPU acceleration for accelerated applications
- X11 Forwarding: GUI application support for RViz and other visualization tools
- DDS Communication: Network and IPC configuration for ROS2 DDS middleware
- Docker (20.10+) with NVIDIA Container Toolkit for GPU support (optional)
- VS Code (1.75+) with Dev Containers extension
- Linux/macOS (or Windows with WSL2)
git clone <repository-url>
cd ros2_control_ws- Open VS Code
- Open the workspace folder
- When prompted, click "Reopen in Container" (or use Command Palette:
Dev Containers: Reopen in Container) - VS Code will build and open the Dev Container
Inside the container terminal:
cd ~/ws
colcon buildsource install/setup.bashThe Dev Container is configured via two files:
Configures VS Code, build context, and container runtime parameters:
- Container Name:
ros2_ws_container - Base Image:
osrf/ros:jazzy-desktop-full - Workspace Mount: Local workspace →
/home/$USER/ws - Extensions: Pre-installed ROS2 development tools
- Environment Variables: ROS settings, ccache, X11 forwarding
Builds the container image with:
- ROS2 Jazzy desktop-full distribution
- Development dependencies (gdb, python3-pip, etc.)
- User account matching host system (avoids permission issues)
- Pre-installed Python packages (bottle, glances)
| Feature | Purpose |
|---|---|
--cap-add=SYS_PTRACE |
Enable debugging with gdb |
--ipc=host |
Shared memory transport (RViz GUIs) |
--network=host |
DDS discovery and network access |
--pid=host |
Process namespace sharing |
--privileged |
USB device access |
--gpus=all |
GPU acceleration |
--runtime=nvidia |
NVIDIA container runtime |
| X11 volume mount | GUI forwarding to host display |
# Full build of entire workspace
colcon build
# Build specific package
colcon build --packages-select <package_name>
# Build with specific mixin (release, debug, ccache, lld)
colcon build --mixin release ccache
# Build without tests
colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release# Source the install space
source install/setup.bash
# Use overlay (if building on top of existing ROS2 installation)
source /opt/ros/jazzy/setup.bash
source install/setup.bash# List available packages
colcon list
# Run a node
ros2 run <package_name> <node_name>
# View the computational graph
ros2 graph# Run a launch file
ros2 launch <package_name> <launch_file>.py
# With arguments
ros2 launch <package_name> <launch_file>.py argument:=valueros2_ws_template/
├── .devcontainer/
│ └── devcontainer.json # VS Code Dev Container configuration
├── src/ # ROS2 source code
│ └── <packages> # Individual ROS2 packages
├── build/ # Colcon build output (generated)
├── install/ # Installation directory (generated)
├── log/ # Colcon log output (generated)
├── Dockerfile # Container image definition
└── README.md # This file
Create new packages in the src/ directory:
# Create a new Python package
ros2 pkg create --build-type ament_python <package_name>
# Create a new C++ package
ros2 pkg create --build-type ament_cmake <package_name># One-time setup (inside container)
cd ~/ws && source /opt/ros/jazzy/setup.bash
# Build everything
colcon build --symlink-install
# Build and test
colcon test
# View test results
colcon test-result --verbose
# Clean build artifacts
colcon clean build --remove-on-error
# Full clean
colcon clean workspace# List packages
ros2 pkg list
# View package info
ros2 pkg prefix <package_name>
# Topic introspection
ros2 topic list
ros2 topic echo <topic_name>
ros2 topic info <topic_name>
# Service discovery
ros2 service list
ros2 service call <service_name> <service_type> "{<args>}"
# Node information
ros2 node list
ros2 node info <node_name>
# Check dependencies
ros2 dependency graph <package_name># View system architecture
ros2 graph
# Record bag file
ros2 bag record <topic_names>
# Play bag file
ros2 bag play <bag_file>
# Check ROS2 environment
ros2 doctorLaunch the ROS2 visualization tool:
rviz2Requirements:
- X11 display forwarding configured in devcontainer.json
- Host X11 socket mounted in container
DISPLAYenvironment variable set
Works with any X11-based application:
- Gazebo simulation
- rqt tools
- Custom visualization applications
Note: GUI forwarding works best on Linux. macOS users may need XQuartz, and Windows users should use WSL2 with X11 support.
The Dev Container is configured for NVIDIA GPU acceleration using the NVIDIA Container Runtime.
# Inside the container
nvidia-smi- NVIDIA GPU with CUDA compute capability 3.5+
- NVIDIA Container Toolkit installed on host
- Docker daemon configured with NVIDIA runtime
Remove "--gpus=all" and "--runtime=nvidia" from devcontainer.json and rebuild.
-
Verify Docker is running:
docker ps
-
Check Docker permissions:
sudo usermod -aG docker $USER -
Rebuild the container:
- Command Palette:
Dev Containers: Rebuild Container
- Command Palette:
-
Check DISPLAY variable:
echo $DISPLAY
-
Verify X11 socket access:
ls -la /tmp/.X11-unix/
-
On Linux, allow X11 access:
xhost +local:
-
Update packages:
sudo apt-get update && sudo apt-get upgrade -
Missing dependencies:
rosdep update rosdep install --from-paths src --ignore-src -y
-
Rebuild from scratch:
colcon clean workspace colcon build
The container creates a user matching your host system UID/GID to avoid permission issues. If problems persist:
# Check user ID
id
# File permissions inside container
ls -la ~/wsThe container uses --network=host and --ipc=host for DDS middleware. Verify with:
ros2 node list
ros2 topic listFor improved code intelligence and navigation in C++ ROS2 packages, you can use Bear to generate a compile_commands.json file and the Clangd extension for VS Code. Both tools are pre-installed in the Dev Container.
Bear is pre-installed and generates compile_commands.json by intercepting compiler invocations. To create the compilation database:
# Clean previous build
colcon clean workspace
# Build with Bear to generate compile_commands.json
bear -- colcon buildThis will create a compile_commands.json file in the workspace root, which contains information about how each source file is compiled.
The Clangd extension (by LLVM) is pre-installed in the Dev Container and provides C++ language server support in VS Code. It will automatically detect the compile_commands.json file and provide features like:
- Code completion
- Go to definition
- Find references
- Hover information
- Error diagnostics
If the extension doesn't automatically find the file, you can configure the path in VS Code settings:
- Open Settings (Ctrl+,)
- Search for "clangd"
- Set "Clangd: Arguments" to include
--compile-commands-dir=/path/to/workspace
Replace /path/to/workspace with your actual workspace path (e.g., /home/$USER/ws).
For more information, refer to the Clangd documentation.