├── config └── ros2 │ └── localhost.env ├── LICENSE ├── docker-compose-ros2-humble-dev.yaml ├── Dockerfile.nvidia-ros2-humble ├── ros2_docker.sh └── README.md /config/ros2/localhost.env: -------------------------------------------------------------------------------- 1 | # ROS 2 Environment Variables 2 | ROS_DOMAIN_ID=25 3 | ROS_LOCALHOST_ONLY=0 4 | 5 | ROS_WORKSPACE=/root/ros2_ws 6 | ROS_LOCATIONS='root=/opt/ros/noetic/share:dev=/root/ros2_ws/install:src=/root/ros2_ws/src' -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Niladri 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docker-compose-ros2-humble-dev.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | x-env-file-common-variables: &env_file 4 | config/ros2/${HOSTNAME}.env 5 | 6 | services: 7 | 8 | ros2-dev: 9 | container_name: ros2-dev 10 | image: ros2-dev:nvidia-humble 11 | network_mode: host 12 | ipc: host # TODO: Investigate issue 13 | build: 14 | context: . 15 | dockerfile: Dockerfile.nvidia-ros2-humble 16 | network: host 17 | environment: 18 | - "DISPLAY" 19 | - "NVIDIA_VISIBLE_DEVICES=all" 20 | - "NVIDIA_DRIVER_CAPABILITIES=all" 21 | # - "ROS_DOMAIN_ID=25" # Optional: to choose ROS domain 22 | # - "ROS_LOCALHOST_ONLY=0" # Optional: set to 1 if you want to present network communication 23 | env_file: *env_file 24 | privileged: true 25 | restart: unless-stopped 26 | # command: bash -c "sleep 3; source " 27 | command: tail -f /dev/null 28 | volumes: 29 | - type: bind 30 | source: /dev 31 | target: /dev 32 | - /tmp/.X11-unix:/tmp/.X11-unix:rw 33 | - $HOME/.Xauthority:/root/.Xauthority:rw 34 | - /var/run/dbus:/var/run/dbus 35 | - $HOME/.ssh:/root/.ssh 36 | - $HOME/logs/docker/ros2:/root/.ros/ 37 | - $HOME/ros2_ws:/root/ros2_ws 38 | - $HOME/ros2-docker-workspace:/root/docker_ws # This repository 39 | 40 | -------------------------------------------------------------------------------- /Dockerfile.nvidia-ros2-humble: -------------------------------------------------------------------------------- 1 | FROM nvidia/cuda:12.2.0-base-ubuntu22.04 2 | 3 | # Ref: https://roboticseabass.com/2021/04/21/docker-and-ros/ 4 | 5 | # Minimal setup 6 | RUN apt-get update \ 7 | && apt-get install -y locales lsb-release 8 | ARG DEBIAN_FRONTEND=noninteractive 9 | RUN dpkg-reconfigure locales 10 | 11 | # Following the ROS2 Humble official setup guide: https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html 12 | 13 | # Locale Setup 14 | RUN locale # check for UTF-8 15 | 16 | RUN apt update && apt install -y --no-install-recommends locales 17 | RUN locale-gen en_US en_US.UTF-8 18 | RUN update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 19 | RUN export LANG=en_US.UTF-8 20 | RUN locale # verify settings 21 | 22 | 23 | # Setup Sources 24 | RUN apt install -y --no-install-recommends software-properties-common 25 | 26 | # Add repository for ROS2 packages 27 | RUN add-apt-repository universe 28 | 29 | RUN apt update && apt install -y --no-install-recommends curl 30 | 31 | RUN curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg 32 | RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null 33 | 34 | 35 | # Install ROS2 Humble 36 | RUN apt update && apt install -y --no-install-recommends ros-humble-desktop 37 | RUN apt update && apt install -y --no-install-recommends ros-dev-tools 38 | 39 | # Install other packages 40 | RUN apt update && apt install -y --no-install-recommends python3-rosdep 41 | RUN apt update && apt install -y --no-install-recommends git 42 | 43 | 44 | RUN rosdep init \ 45 | && rosdep fix-permissions \ 46 | && rosdep update 47 | 48 | 49 | 50 | 51 | 52 | #Python packages 53 | RUN apt install -y --no-install-recommends python3-pip 54 | RUN pip3 install -U catkin_tools 55 | 56 | 57 | # Setup 58 | RUN echo "\n\ 59 | source /opt/ros/humble/setup.bash" >> /root/.bashrc 60 | 61 | RUN echo "\n\ 62 | if [ -f /root/ros2_ws/install/setup.bash ]; then source /root/ros2_ws/install/setup.bash; fi\n\ 63 | export ROS_WORKSPACE=/root/ros2_ws\n\ 64 | export ROS_LOCATIONS='root=/opt/ros/noetic/share:dev=/root/ros2_ws/install:src=/root/ros2_ws/src'\n\ 65 | export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/lib" >> /root/.bashrc 66 | 67 | # Set ROS2 Environment Variables 68 | ENV ROS_DISTRO=humble 69 | ENV AMENT_PREFIX_PATH=/opt/ros/humble 70 | ENV COLCON_PREFIX_PATH=/opt/ros/humble 71 | 72 | 73 | # Set up aliases 74 | RUN echo "\n\ 75 | alias rcsource='source ~/.bashrc'\n\ 76 | alias k='ros2 run teleop_twist_keyboard teleop_twist_keyboard.py'" >> /root/.bash_aliases 77 | 78 | 79 | 80 | # RUN mkdir -p /root/catkin_ws/src 81 | # WORKDIR /root/catkin_ws/src 82 | # RUN catkin_create_pkg ros_package std_msgs rospy roscpp 83 | WORKDIR /root/ros2_ws 84 | # RUN /bin/bash -c "source /ros_entrypoint.sh && catkin build" 85 | 86 | 87 | # COPY ./ros2_entrypoint.sh / 88 | # ENTRYPOINT ["/ros2_entrypoint.sh"] 89 | # RUN ["chmod", "+x", "/ros2_entrypoint.sh"] 90 | # CMD ["/bin/sh", "-c"] -------------------------------------------------------------------------------- /ros2_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set_hostname() { 4 | # Set hostname to current system hostname 5 | if [[ -z ${HOSTNAME} ]]; then 6 | export HOSTNAME="localhost" 7 | else 8 | echo "HOSTNAME is set: $HOSTNAME" 9 | export HOSTNAME 10 | fi 11 | 12 | FILE=config/ros2/${HOSTNAME}.env 13 | if [ -f "$FILE" ]; then 14 | echo "Environment Config file exists: $FILE" 15 | else 16 | echo "Environment Config file NOT FOUND: $FILE" 17 | if [[ $HOSTNAME == localhost ]]; then 18 | echo "Exiting" 19 | exit 20 | else 21 | export HOSTNAME="localhost" 22 | FILE=config/ros2/${HOSTNAME}.env 23 | echo "Trying default env file: $FILE" 24 | if [ -f "$FILE" ]; then 25 | echo "Environment Config file exists: $FILE" 26 | else 27 | echo "Environment Config file NOT FOUND: $FILE" 28 | if [[ $HOSTNAME == localhost ]]; then 29 | echo "Exiting" 30 | exit 31 | fi 32 | fi 33 | fi 34 | 35 | fi 36 | 37 | } 38 | 39 | start_module() { 40 | # Enable GUI passthorugh 41 | xhost + 42 | 43 | # Set hostname to current system hostname 44 | set_hostname 45 | 46 | # Start docker container 47 | docker compose -f docker-compose-ros2-humble-dev.yaml up -d 48 | # docker compose -f docker-compose-ros2-humble-dev.yaml up -d rosmaster & 49 | # docker compose -f docker-compose-ros2-humble-dev.yaml up -d ros-dev & 50 | 51 | } 52 | 53 | stop_module() { 54 | # Set hostname to current system hostname 55 | set_hostname 56 | 57 | # Build docker container 58 | docker compose -f docker-compose-ros2-humble-dev.yaml pull 59 | docker compose -f docker-compose-ros2-humble-dev.yaml down 60 | } 61 | 62 | restart_module() { 63 | stop_module 64 | sleep 5 65 | start_module 66 | } 67 | 68 | build_module() { 69 | # Set hostname to current system hostname 70 | set_hostname 71 | 72 | # Start docker container 73 | docker compose -f docker-compose-ros2-humble-dev.yaml build 74 | } 75 | 76 | usage_message() { 77 | 78 | # Define a file path 79 | filepath=$0 80 | 81 | # Extract the filename and extension from the file path 82 | filename=$(basename "$filepath") 83 | echo "Usage: $filename start | stop | restart | build " 84 | } 85 | 86 | if [ $# != 1 ]; then # If Argument is not exactly one 87 | usage_message 88 | 89 | exit 1 # Exit the program 90 | fi 91 | 92 | 93 | ARGUMENT=$(echo "$1" | awk '{print tolower($0)}') # Converts Argument in lower case. This is to make user Argument case independent. 94 | 95 | if [[ $ARGUMENT == start ]]; then 96 | 97 | start_module 98 | 99 | elif [[ $ARGUMENT == stop ]]; then 100 | 101 | stop_module 102 | 103 | elif [[ $ARGUMENT == build ]]; then 104 | 105 | build_module 106 | 107 | elif [[ $ARGUMENT == restart ]]; then 108 | 109 | restart_module 110 | 111 | else 112 | usage_message 113 | fi 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ROS 2 Docker Development Environment 2 | 3 | This repository provides a step-by-step guide to set up a ROS 2 development environment within a Docker container on your local computer. Using Docker ensures a consistent and isolated environment for your ROS 2 projects, and integrating it with Visual Studio Code (VSCode) enhances your development experience. 4 | 5 | This repository is for setting up the ROS2 development workspace. For ROS Noetic Docker development environment see this repository: [ros-docker-workspace](https://github.com/niladut/ros-docker-workspace) 6 | 7 | ## Prerequisites 8 | 9 | Before you begin, make sure you have the following prerequisites: 10 | 11 | 1. **OS:** Ubuntu is recommended). 12 | 2. **Docker** installed on your system. Installation instructions on the official website: [Install Docker](https://docs.docker.com/get-docker/). 13 | 3. **VSCode** installed on your system. Installation instructions on the official website: [Install VSCode](https://code.visualstudio.com/Download) 14 | 15 | ## Steps 16 | 17 | Follow these steps to set up the ROS 2 development environment: 18 | 19 | ### 1. Clone the Repository 20 | 21 | Clone this repository to your local machine: 22 | 23 | ```bash 24 | git clone https://github.com/niladut/ros2-docker-workspace.git 25 | cd ros2-docker-workspace 26 | ``` 27 | 28 | ### 2. Docker Compose Configuration 29 | The Docker Compose configuration file `docker-compose-ros2-humble-dev.yml` creates a ROS 2 development environment in a Docker container with network and device access, allowing for efficient development and debugging. 30 | 31 | `docker-compose-ros2-humble-dev.yml` : 32 | 33 | ```yaml 34 | version: "3.7" 35 | 36 | x-env-file-common-variables: &env_file 37 | config/ros2/${HOSTNAME}.env 38 | 39 | services: 40 | 41 | ros2-dev: 42 | container_name: ros2-dev 43 | image: ros2-dev:nvidia-humble 44 | network_mode: host 45 | ipc: host # TODO: Investigate issue 46 | build: 47 | context: . 48 | dockerfile: Dockerfile.nvidia-ros2-humble 49 | network: host 50 | environment: 51 | - "DISPLAY" 52 | - "NVIDIA_VISIBLE_DEVICES=all" 53 | - "NVIDIA_DRIVER_CAPABILITIES=all" 54 | # - "ROS_DOMAIN_ID=25" # Optional: to choose ROS domain 55 | # - "ROS_LOCALHOST_ONLY=0" # Optional: set to 1 if you want to present network communication 56 | env_file: *env_file 57 | privileged: true 58 | restart: unless-stopped 59 | # command: bash -c "sleep 3; source " 60 | command: tail -f /dev/null 61 | volumes: 62 | - type: bind 63 | source: /dev 64 | target: /dev 65 | - $HOME/logs/docker/ros2:/root/.ros/ 66 | - $HOME/user/ros2_ws:/root/ros2_ws 67 | - $HOME/user/docker_ws:/root/docker_ws 68 | - /tmp/.X11-unix:/tmp/.X11-unix:rw 69 | - $HOME/.Xauthority:/root/.Xauthority:rw 70 | - /var/run/dbus:/var/run/dbus 71 | - $HOME/.ssh:/root/.ssh 72 | ``` 73 | 74 | 75 | #### 2.1 Sharing Folders with the Docker container 76 | Sharing the access to folders on the host system to the docker container can be done by binding the paths for these folders with a path inside the docker container. This is done by configuring the `volumes` section of the docker container service: 77 | ```yaml 78 | volumes: 79 | - type: bind 80 | source: /dev 81 | target: /dev 82 | - $HOME/logs/docker/ros2:/root/.ros/ 83 | - $HOME/user/ros2_ws:/root/ros2_ws 84 | - $HOME/user/docker_ws:/root/docker_ws 85 | - /tmp/.X11-unix:/tmp/.X11-unix:rw 86 | - $HOME/.Xauthority:/root/.Xauthority:rw 87 | - /var/run/dbus:/var/run/dbus 88 | - $HOME/.ssh:/root/.ssh 89 | ``` 90 | The configuration assumes certain directory structures (`$HOME/logs/docker/ros2`, `$HOME/user/ros2_ws`, etc.). You can add your custom folder paths in by adding a new entry under the `volumes` section: 91 | ```yaml 92 | volumes: 93 | . 94 | . 95 | . 96 | - : 97 | ``` 98 | This configuration sets up a service named `ros2_container` using the Docker image built from the provided `Dockerfile`. It also mounts a local `workspace` directory into the container, allowing file sharing between the host and the container. 99 | 100 | 101 | #### 2.2 Environment Variable Configuration 102 | The project defines the system and ROS environemnt variables required in the docker container in the following sections: 103 | - `environment` : Sets environment variables for the container, including "DISPLAY", "NVIDIA_VISIBLE_DEVICES", and "NVIDIA_DRIVER_CAPABILITIES". 104 | - `env_file`: Loads environment variables from the common environment file `config/ros2/${HOSTNAME}.env`. 105 | 106 | To create a custom environment variable configuration file for the current host system with (`$HOSTNAME`), make a duplicate of the default environment configuration file (`config/ros2/localhost.env`) and place it at `config/ros2/${HOSTNAME}.env`. 107 | 108 | For example, if the system hostname is `mypc`, then follow the following commands: 109 | ```bash 110 | cd config/ros2/ 111 | cp localhost.env mypc.env 112 | ``` 113 | 114 | The environment variable `${HOSTNAME}` is usually set to the hostname of the current system (in Ubuntu). If it is not defined, and if the current system hostname is `mypc`, it can define by: 115 | ```bash 116 | export HOSTNAME=mypc 117 | ``` 118 | 119 | ### 3. Using the Bash Script 120 | 121 | The provided Bash script simplifies the management of your ROS 2 Docker development environment. It offers commands to start, stop, restart, or build the environment using Docker Compose. The scipt will work on Ubuntu and OSX operating systems. If you are on Windows, you can refer to the docker commands in the `ros2_docker.sh` bash scipt file. 122 | 123 | 124 | Here's how to use the `ros2_docker.sh` script on Ubuntu or OSX: 125 | 126 | #### 3.1. Setting Up Environment Variables: 127 | 128 | The script uses an environment configuration file located in `config/ros2/${HOSTNAME}.env` to set up environment variables. You can create this file and define environment variables as needed for your ROS 2 environment. 129 | 130 | #### 3.2. Understanding the Commands: 131 | 132 | The script supports the following commands: 133 | 134 | - `start`: Starts the ROS 2 Docker environment by executing the specified Docker Compose file. 135 | - `stop`: Stops and removes the Docker containers defined in the Docker Compose file. 136 | - `restart`: Stops, rebuilds, and restarts the Docker containers. 137 | - `build`: Builds the Docker containers defined in the Docker Compose file. 138 | #### 3.3. Running the Script: 139 | 140 | Open a terminal and navigate to the directory where the script is located. Then, use the following syntax to execute the script with a specific command: 141 | 142 | ```bash 143 | ./ros2_docker.sh command 144 | 145 | ``` 146 | 147 | Replace `command` with one of the commands mentioned above (e.g., `start`, `stop`, `restart`, `build`). 148 | 149 | **Example:** 150 | 151 | To start the ROS 2 Docker environment, execute: 152 | 153 | ```bash 154 | ./ros2_docker.sh start 155 | ``` 156 | 157 | To stop the environment, execute: 158 | 159 | ```bash 160 | ./ros2_docker.sh stop 161 | ``` 162 | 163 | To rebuild and restart the environment, execute: 164 | 165 | ```bash 166 | ./ros2_docker_script.sh restart 167 | ``` 168 | 169 | To build the Docker containers, execute: 170 | 171 | ```bash 172 | ./ros2_docker_script.sh build 173 | ``` 174 | 175 | If you're unsure about the available commands, running the script without any arguments will display a usage message: 176 | 177 | ```bash 178 | ./ros2_docker_script.sh 179 | ``` 180 | 181 | This will provide information about using the script and the available commands. 182 | 183 | The provided script helps you manage your ROS 2 Docker development environment with ease, automating various Docker-related tasks and allowing you to focus on your robotics projects. 184 | 185 | 186 | 187 | ### 4. Set Up Development Environment with VSCode 188 | 189 | Setting Up a Development Environment with VSCode and Docker for ROS2 190 | 191 | #### Step 4.1: Install the "Dev Containers" Extension 192 | 193 | Begin by installing the "Dev Containers" extension in VSCode. 194 | 195 | #### Step 4.2: Open Project in VSCode 196 | 197 | 1. Launch VSCode and open your project directory. 198 | 2. After starting the Docker container (as described earlier), press `Ctrl` + `Shift` + `P` (or `Cmd` + `Shift` + `P` on macOS). 199 | 3. Type "Dev Containers: Attach to running container" and select the running container. 200 | 4. VSCode will open a new window within the container, providing a seamless development environment. 201 | 202 | #### Step 4.3: Open ROS2 Workspace 203 | 204 | 1. In the new window, navigate to **"File > Open Folder..."**. 205 | 2. Choose the `/root/ros2_ws` folder inside the container to open. 206 | 207 | #### Step 4.4: Edit Files 208 | 209 | 1. Use the left sidebar file explorer to select and edit files for development. 210 | 2. Changes made in the `/root/ros2_ws` folder of the VSCode Dev Container environment will be saved directly to the local host system, persisting even when the container is stopped. 211 | 212 | For more detailed information, refer to the [Developing inside a Container](https://code.visualstudio.com/docs/devcontainers/containers) guide. 213 | 214 | 215 | ## Command Line for the Docker Container 216 | 217 | Open a shell terminal linked to the Docker container: 218 | 219 | 1. Navigate to **"Terminal > New Terminal"** in VSCode. 220 | 2. A shell terminal will open for executing commands within the ROS2 docker container. 221 | 222 | 223 | You can also link any shell terminal on the host system to the Docker container using the following command (on Ubuntu): 224 | 225 | ``` 226 | docker exec -it ros2-dev bash 227 | ``` 228 | 229 | 230 | ## Graphical Applications with Docker 231 | 232 | Running the script with the start argument lets you run GUI applications like gazebo or rviz2 from any shell terminal linked to the ros2-dev Docker container. (Tested on Ubuntu.) 233 | 234 | 235 | ## Feedback 236 | 237 | Feel free to explore advanced features like hardware device access, using ROS packages, and further customization within the Docker environment. 238 | Also feel free to suggest improvements and features by creating [issues](https://github.com/niladut/ros2-docker-workspace/issues) or posting in the [discussions](https://github.com/niladut/ros2-docker-workspace/discussions). 239 | 240 | ## Additional Referneces and Links 241 | 242 | - [VSCode, Docker, and ROS2 -- by Allison Thackston](https://www.allisonthackston.com/articles/vscode-docker-ros2.html) 243 | - [A Guide to Docker and ROS -- by Robotic Sea Bass](https://roboticseabass.com/2021/04/21/docker-and-ros/) 244 | 245 | 246 | ## Author 247 | 248 | This ROS 2 Docker Workspace guide was authored by [Niladri Dutta](https://github.com/niladut). 249 | 250 | Happy coding! 🤖🐍🐬 251 | --------------------------------------------------------------------------------