This is the official development environment for ROS 2 Humble used by the SDU Vikings Driverless Team. It runs in a Docker container via VS Code to ensure a consistent setup across Linux, macOS, and Windows. The purpose of this standardization is to eliminate the classic “works on my machine” problem.
Before you get started, you will need to install a few things on your computer.
Docker runs the container that has all our ROS 2 tools and dependencies.
Linux:
# Install Docker Engine
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add your user to docker group (so you do not need sudo)
sudo usermod -aG docker $USER
# Log out and back in, then verify
docker --versionOr follow the official guide: https://docs.docker.com/engine/install/
macOS or Windows: Download and install Docker Desktop:
- macOS: https://docs.docker.com/desktop/install/mac-install/
- Windows: https://docs.docker.com/desktop/install/windows-install/
After installing, verify it works:
docker --version
docker compose versionWe use VS Code to connect to the container and do our development inside it.
Download from: https://code.visualstudio.com/download
You will need the Dev Containers extension. Install it from: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
Or search for "Dev Containers" in VS Code's extension marketplace.
That is it for requirements! The container itself comes with everything else (ROS 2, Python packages, C++ tools, etc.).
First, grab the code:
git clone https://github.com/SDU-Vikings-Racing-Team/ros-devcontainer.git
cd ros-devcontainerOpen the project folder:
code .VS Code will detect the .devcontainer folder and show you a notification in the bottom right corner asking if you want to "Reopen in Container". Click that button.
Alternatively, you can:
- Press
F1(orCtrl+Shift+Pon Linux/Windows,Cmd+Shift+Pon macOS) - Type "Dev Containers: Reopen in Container"
- Press Enter
The first time you open the container, it will take a few minutes because it needs to:
- Figure out your environment (do you have X11 for GUI apps? Are we in CI?)
- Build the Docker image with ROS 2 and all the tools
- Set up the workspace structure
- Link any packages you have in the
src/folder - Install dependencies
- Build everything
You will see all this happening in the VS Code terminal. Once it is done, open a new Bash terminal and you are ready to go!
When you are inside the container, here is what you get.
Everything lives under /home/rosdev/ros_ws/:
/home/rosdev/ros_ws/
├── src/
│ ├── host_packages/ # Your packages (symlinked from ../src on host)
│ └── thirdparty_packages/ # External dependencies
├── build/ # Build artifacts
├── install/ # Installed packages
├── log/ # Build and test logs
├── bags/ # ROS bag recordings
└── scripts/ # Utility scripts
Your packages that live in the src/ folder on your host machine are automatically linked into src/host_packages/ in the container. This means you can edit files on your host with any editor you like, and the changes show up immediately in the container.
The container automatically sets up ROS 2 for you. When you open a new terminal, it does the following:
- Sources the ROS 2 Humble environment
- Sources your workspace overlay
- Sets up helpful aliases (more on these below)
- Puts you in the workspace directory
We have some convenient aliases to make building easier:
# Build everything
cb
# Build just one package
cbp my_package_name
# Build a package and all its dependencies
cbu my_package_nameThese are shortcuts for colcon build with our standard arguments already configured (symlink install, compile commands for IDE, release mode, etc.).
After building, run your nodes like normal:
# Run a node
ros2 run my_package my_node
# Launch a launch file
ros2 launch my_package my_launch_file.pyThe environment is already sourced, so your packages are immediately available.
# Run all tests
ct
# Test a specific package
ctp my_package_name
# Show test results
ctrIf you need to clean everything and rebuild from scratch:
clean_ws # Removes build/, install/, and log/
cb # Build everything againCreate packages in the src/ folder on your host machine (not inside the container):
# On your host computer, in the project root
cd src
ros2 pkg create --build-type ament_cmake my_new_packageThe next time you open the container (or run the setup script), it will automatically get linked and you can build it.
If you want it available immediately without restarting:
# Inside the container
bash /home/rosdev/ros_ws/scripts/setup.shWe use a packages.repos file to manage third party packages. This uses the VCS tool format.
- Edit
.devcontainer/packages.repos:
repositories:
some_dependency:
type: git
url: https://github.com/org/some_dependency.git
version: humble- Import the packages:
cd /home/rosdev/ros_ws/src/thirdparty_packages
vcs import < /home/rosdev/ros_ws/packages.repos- Install dependencies and build:
rosdep_install # Alias for rosdep install
cb # Build everythingThe container comes with Foxglove Bridge for visualizing data.
Start the bridge:
foxgloveThis starts a WebSocket server on port 8765. Then open Foxglove Studio (either the desktop app or https://studio.foxglove.dev) and connect to:
ws://localhost:8765
Note: You will need to sign in with a Foxglove account to access Foxglove Studio. If you do not have one, you can create it for free on their website.
You can customize the port in .devcontainer/config/defaults.env if needed.
Here is a quick reference of the aliases and commands you will use most often.
cb # Build all packages
cbp <pkg> # Build specific package
cbu <pkg> # Build package and its dependencies
ct # Test all packages
ctp <pkg> # Test specific package
ctr # Show test results
clean_ws # Remove build artifacts
source_ws # Re-source the workspace# See what is running
ros2 node list
ros2 topic list
# Monitor a topic
ros2 topic echo /my_topic
# Check topic info
ros2 topic info /my_topic
# See available services
ros2 service listThe container automatically detects if you have X11 available on your host. If you do, GUI applications like RViz2 will work out of the box:
rviz2On Linux, this should just work. On macOS or Windows, you might need to set up an X server (like XQuartz or VcXsrv).
First, check Docker is running:
docker psIf that fails, start Docker Desktop or the Docker daemon.
Try regenerating the environment setup:
bash .devcontainer/host-setup.shThen rebuild:
docker compose -f .devcontainer/docker-compose.yml build --no-cacheThis usually means your user ID does not match what the container expects (1000).
Check your ID:
idIf you are not 1000:1000, edit .devcontainer/docker-compose.yml and change:
services:
ros2-dev:
build:
args:
DEV_USER_ID: <your-uid>
DEV_GROUP_ID: <your-gid>Then rebuild the container.
The environment should auto source, but if it does not:
source_wsOr manually:
source /opt/ros/humble/setup.bash
source /home/rosdev/ros_ws/install/setup.bashFor packages in src/:
bash /home/rosdev/ros_ws/scripts/setup.shFor packages in packages.repos:
cd /home/rosdev/ros_ws/src/thirdparty_packages
vcs import < /home/rosdev/ros_ws/packages.repos
rosdep_install
cbSometimes the build cache gets stale. Clean and rebuild:
clean_ws
cbIf that does not work, completely reset the container:
# On host
docker compose -f .devcontainer/docker-compose.yml down -v
docker compose -f .devcontainer/docker-compose.yml up -dYou can customize the environment by editing .devcontainer/config/defaults.env:
# ROS configuration
ROS_DISTRO=humble
ROS_DOMAIN_ID=7
# Build configuration
BUILD_TYPE=Release
# Foxglove
FOXGLOVE_PORT=8765After changing configuration, rebuild the container for changes to take effect.
If you prefer to work without VS Code, you can still use the container:
# Generate environment specific config
bash .devcontainer/host-setup.sh
# Start the container
docker compose -f .devcontainer/docker-compose.yml \
-f .devcontainer/docker-compose.override.yml \
up -d
# Enter the container
docker compose -f .devcontainer/docker-compose.yml \
-f .devcontainer/docker-compose.override.yml \
exec ros2-dev bash
# You are now inside the container
cd /home/rosdev/ros_wsWhen the devcontainer configuration gets updated (new dependencies, ROS packages, etc.), you will need to rebuild.
Using VS Code:
- Press
F1 - Type "Dev Containers: Rebuild Container"
- Press Enter
Using Docker Compose:
docker compose -f .devcontainer/docker-compose.yml build --no-cache
docker compose -f .devcontainer/docker-compose.yml up -dBuilds already use all your CPU cores by default. But if you want to limit it:
colcon build --parallel-workers 4colcon build --packages-up-to my_packageThis rebuilds my_package and anything it depends on, but skips unrelated packages.
Your bash history persists between container sessions. It is stored in your home directory on the host, so you will not lose your command history when rebuilding.
You can open multiple terminals in VS Code (Terminal → New Terminal), and they will all be inside the container. Each one is a separate bash session, so you can run multiple nodes simultaneously.
If you run into issues:
- Check the Common Issues section above
- Look at the container logs:
docker compose logs - Search our GitHub issues to see if others have encountered the same problem
- Ask in the team chat with a brief description of your issue and relevant logs
If you have identified a bug, please report it as a GitHub issue using the Bug template in this repository. Include details about how the bug occurred and any error messages you encountered.
Found a bug or want to add a feature? Contributions are welcome!
- Create a branch from
main(usefeature/feature_nameorfix/bug_descriptionformat) - Make your changes
- Test that the devcontainer still builds and works correctly
- Update the README or other documentation if your changes affect usage
- Open a pull request with a clear description of your changes
The CI workflow will automatically test that the container builds correctly.