Skip to content

Docker Environment

The entire simulation environment runs inside a Docker container managed by VS Code Dev Containers. This ensures everyone on the team has an identical setup regardless of their host OS.

FROM ros:humble-ros-base

This gives us Ubuntu Jammy 22.04 with ROS 2 Humble pre-installed.

PackagePurpose
Gazebo Ignition FortressPhysics simulation engine
ros-humble-ros-gz-simROS 2 / Gazebo integration
ros-humble-ros-ign-bridgeMessage bridging between ROS and Gazebo
ros-humble-ros2-controllersJoint state broadcaster + trajectory controller
ros-humble-gz-ros2-controlHardware interface for Gazebo
ros-humble-rviz2Robot visualization
ros-humble-xacroURDF macro processing
ros-humble-joint-state-publisher-guiJoint state publishing GUI
PackagePurpose
xserver-xorg-core + xserver-xorg-video-dummyVirtual X server with no real GPU
openboxLightweight window manager
x11vncVNC server for remote X11 access
novnc + websockifyBrowser-based VNC client
mesa-utils, libgl1-mesa-*Software OpenGL rendering
PackagePurpose
onshape-to-robotCAD-to-URDF conversion (used by genbot)
open3dSTL mesh decimation
ruffPython linter
moteusMotor controller interface (for hardware integration)
opencv-pythonComputer vision
PackagePurpose
python3-colcon-common-extensionsROS 2 workspace build system
python3-rosdepROS dependency installer
gitVersion control

The container runs as a non-root user trickfire with passwordless sudo. This matches standard development practices and avoids permission issues.

RUN useradd trickfire --shell /bin/bash --create-home
RUN echo "trickfire ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/user

The devcontainer.json configures how VS Code opens the container:

Workspace mount: The repo is bind-mounted into the container at /home/trickfire/gazebo-simulations.

Port forwarding: Ports 6080 (noVNC) and 5900 (VNC) are forwarded to the host.

Privileged mode: The container runs with --privileged and device access for hardware interaction (USB, CAN bus).

Post-create command: scripts/clean_build.sh runs automatically to clear stale build artifacts.

VS Code extensions: Pre-installs Python, C++, ROS, URDF, Docker, and formatting extensions.

Since Docker containers have no monitor, we use a virtual X11 server so Gazebo and RViz can render.

Xorg (dummy driver) → x11vnc → websockify → Browser
↑ ↑
Openbox WM noVNC client
↑ (port 6080)
Gazebo / RViz

The custom X11 config at /etc/X11/xorg.conf defines a fake display:

SectionPurpose
ModuleLoads GLX extension for OpenGL support inside X11
DeviceCreates a virtual GPU using the dummy driver with 256 MB of virtual VRAM
MonitorDefines a fake monitor with plausible refresh rates
ScreenSets the resolution and 24-bit color depth
ServerLayoutTies everything together into one virtual display
VariableValueSet in
DISPLAY:1Dockerfile / launch.env
VNC_PORT5900Dockerfile
NOVNC_PORT6080Dockerfile

Alternatives like Xvfb don’t support GLX properly, which means Gazebo’s 3D rendering fails. Using Xorg with a dummy driver + Mesa software rendering gives us full OpenGL support without needing a real GPU. The VNC + noVNC layer makes it accessible from any browser.

To add system packages, edit .devcontainer/Dockerfile and rebuild the container. For Python packages, add them to the pip3 install section.

After changing the Dockerfile, use Dev Containers: Rebuild Container in VS Code’s Command Palette.