devcontainer
docker
gazebo
gz
harmonic
vscode
Use gazebo harmonic with vscode devcontainer
Use VSCode and docker
Using docker-compose
Using devcontainer to run the docker compose
├── .devcontainer
│ ├── Dockerfile
│ └── devcontainer.json
├── docker-compose.yaml
├── .gitignore
└── worlds
└── empty.world
Dockerfile
FROM ubuntu:22.04 as base
# Avoid warnings by switching to noninteractive
ENV DEBIAN_FRONTEND=noninteractive
# Install language
RUN apt-get update && apt-get install -y --no-install-recommends \
locales \
&& locale-gen en_US.UTF-8 \
&& update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 \
&& rm -rf /var/lib/apt/lists/*
ENV LANG=en_US.UTF-8
# Install timezone
RUN ln -fs /usr/share/zoneinfo/UTC /etc/localtime \
&& export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get install -y --no-install-recommends tzdata \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& rm -rf /var/lib/apt/lists/*
# install packages
RUN apt-get update && apt-get install -q -y \
curl \
gnupg \
lsb-release \
python3-argcomplete \
sudo \
wget \
&& wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null \
&& apt-get update && apt-get install -y -q \
gz-harmonic \
&& rm -rf /var/lib/apt/lists/*
################
# Expose the nvidia driver to allow opengl
# Dependencies for glvnd and X11.
################
RUN apt-get update \
&& apt-get install -y -qq --no-install-recommends \
libglvnd0 \
libgl1 \
libglx0 \
libegl1 \
libxext6 \
libx11-6 \
&& rm -rf /var/lib/apt/lists/*
# Env vars for the nvidia-container-runtime.
ENV NVIDIA_VISIBLE_DEVICES=all
ENV NVIDIA_DRIVER_CAPABILITIES=graphics,utility,compute
ENV QT_X11_NO_MITSHM=1
ARG USERNAME=user
ARG USER_UID=1000
ARG USER_GID=$USER_UID
# Check if "ubuntu" user exists, delete it if it does, then create the desired user
RUN if getent passwd ubuntu > /dev/null 2>&1; then \
userdel -r ubuntu && \
echo "Deleted existing ubuntu user"; \
fi && \
groupadd --gid $USER_GID $USERNAME && \
useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME && \
echo "Created new user $USERNAME"
# Add sudo support for the non-root user
RUN apt-get update && apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
&& chmod 0440 /etc/sudoers.d/$USERNAME \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& apt-get install -y -qq --no-install-recommends \
vim \
build-essential \
git \
openssh-client \
ca-certificates \
cmake \
&& rm -rf /var/lib/apt/lists/*
CMD ["bash"]
docker-compose
docker-compose.yaml services :
gazebo :
build :
dockerfile : .devcontainer/Dockerfile
context : .
network_mode : host
user : user
stdin_open : true
tty : true
hostname : gz
environment :
- DISPLAY=${DISPLAY}
- QT_X11_NO_MITSHM=1
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
- __NV_PRIME_RENDER_OFFLOAD=1
- __GLX_VENDOR_LIBRARY_NAME=nvidia
- GZ_TRANSPORT_IP=gazebo
- GZ_DISCOVERY_SERVER=gazebo
- GZ_PARTITION=my_simulation
volumes :
- .:/workspace:cached
- ./.gz:/home/user/.gz:rw
- /tmp/.X11-unix:/tmp/.X11-unix:rw
- /dev/dri:/dev/dri
- /dev/nvidia0:/dev/nvidia0
- /dev/nvidiactl:/dev/nvidiactl
- /dev/nvidia-modeset:/dev/nvidia-modeset
deploy :
resources :
reservations :
devices :
- capabilities : [ gpu ]
nvidia glx
__NV_PRIME_RENDER_OFFLOAD=1
__GLX_VENDOR_LIBRARY_NAME=nvidia
.devcontainer/devcontainer.json {
"name" : "gz_harmonic" ,
"dockerComposeFile" : "../docker-compose.yaml" ,
"service" : "gazebo" ,
"shutdownAction" : "stopCompose" ,
"workspaceFolder" : "/workspace" ,
"customizations" : {
"vscode" : {
"extensions" : [
"ms-python.python" ,
"ms-vscode.cpptools" ,
"redhat.vscode-xml" ,
"redhat.vscode-yaml" ,
"albert.tabout" ,
"actboy168.tasks" ,
"streetsidesoftware.code-spell-checker" ,
"ms-vscode.cmake-tools"
],
"settings" : {}
}
}
}
Run the simulation
minimal world
<?xml version="1.0"?>
<sdf version= "1.8" >
<world name= "world_demo" >
<physics name= "1ms" type= "ignored" >
<max_step_size> 0.001</max_step_size>
<real_time_factor> 1.0</real_time_factor>
</physics>
<plugin
filename= "gz-sim-physics-system"
name= "gz::sim::systems::Physics" >
</plugin>
<plugin
filename= "gz-sim-user-commands-system"
name= "gz::sim::systems::UserCommands" >
</plugin>
<plugin
filename= "gz-sim-scene-broadcaster-system"
name= "gz::sim::systems::SceneBroadcaster" >
</plugin>
<!--light-->
<light type= "directional" name= "sun" >
<cast_shadows> true</cast_shadows>
<pose> 0 0 10 0 0 0</pose>
<diffuse> 0.8 0.8 0.8 1</diffuse>
<specular> 0.2 0.2 0.2 1</specular>
<attenuation>
<range> 1000</range>
<constant> 0.9</constant>
<linear> 0.01</linear>
<quadratic> 0.001</quadratic>
</attenuation>
<direction> -0.5 0.1 -0.9</direction>
</light>
<model name= "ground_plane" >
<static> true</static>
<link name= "link" >
<collision name= "collision" >
<geometry>
<plane>
<normal> 0 0 1</normal>
<size> 100 100</size>
</plane>
</geometry>
</collision>
<visual name= "visual" >
<geometry>
<plane>
<normal> 0 0 1</normal>
<size> 100 100</size>
</plane>
</geometry>
<material>
<ambient> 0.8 0.8 0.8 1</ambient>
<diffuse> 0.8 0.8 0.8 1</diffuse>
<specular> 0.8 0.8 0.8 1</specular>
</material>
</visual>
</link>
</model>
</world>
</sdf>
Environment helper file
Change prompt
Set Environment variables
Add keyboard shortcuts
env.sh export GZ_SIM_RESOURCE_PATH = $( pwd ) /models:$( pwd ) /worlds:$GZ_SIM_RESOURCE_PATH
export GZ_SIM_SYSTEM_PLUGIN_PATH = $( pwd ) /bin:$GZ_SIM_SYSTEM_PLUGIN_PATH
echo '🤖 Environment ready!'
# bash key bindings
# replace bringup with full bringup name
bind '"\C-b": "gz sim -v 4 -r mini.world"'
# Function to get git branch
parse_git_branch() {
git branch 2 > /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/[\1]/'
}
# Custom PS1 with turtle icon and git branch
export PS1 = "🤖 \[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[33m\]\$(parse_git_branch)\[\033[00m\]\$ "
Usage
# run the simulation
gz sim -r v 4 gz_tutorial/worlds/mini.world
gz topic gz topic --list
gz topic -e -t /clock
#
sim {
sec: 326
nsec: 476000000
}
Gz Transport
gz_transport is Gazebo's communication middleware, used for inter-process communication (IPC) between different Gazebo components — like sensors, plugins, UI, and even ROS bridges.
GZ_PARTITION : Isolates topic namespaces between different simulations
GZ_DISCOVERY_SERVER : IP address of the main discovery server (usually the Gazebo server machine)
GZ_TRANSPORT_IP : IP address the local process uses to advertise itself to others
Resource