Author: Tobit Flatscher (August 2021 - September 2022)
I personally think that Docker is a good choice for developing robotic applications as it allows you to quickly switch between different projects but less so for deploying software. Refer to this Canonical article to more details about the drawbacks of deploying software with Docker, in particular regarding security. For the deployment I personally would rather turn to Debian or Snap packages (see e.g. Bloom).
The ROS Wiki offers tutorials on ROS and Docker here, there is also a very useful tutorial paper out there and another interesting article can be found here. Furthermore a list of important commands can be found here. After installing Docker one simply pulls an image of ROS, specifying the version tag:
$ sudo docker pull ros
gives you the latest ROS2 version whereas
$ sudo docker pull ros:noetic-robot
will pull the latest version of ROS1.
Finally you can run it with
$ sudo docker run -it ros
(where ros
should be replaced by the precise version tag e.g. ros:noetic-robot
).
In case of a Docker you do not source the /opt/ros/<distro>/setup.bash
file but instead the entrypoint script:
$ source ros_entrypoint.sh
I generally structure Dockers for ROS in the following way:
ros_ws
├─ docker
| ├─ Dockerfile
| └─ docker-compose.yml # Context is chosen as ..
└─ src # Only this folder is mounted into the Docker
├─ .repos # Configuration file for VCS tool
└─ packages_as_submodules
Each ROS-package or a set of ROS packages are bundled together in a Git repository. These are then included as submodules in the src
folder or by using VCS tool. Inside the docker-compose.yml
file one then mounts only the src
folder as volume so that it can be also accessed from within the container. This way the build and devel folders remain inside the Docker container and you can compile the code inside the Docker as well as outside (e.g. having two version of Ubuntu and ROS for testing).
Generally I have more than a single docker-compose.yml
as discussed in Gui.md
and I will add configuration folders for Visual Studio Code and a configuration for the Docker itself, as well as dedicated tasks. I usually work inside the container and install new software there first. I will keep then track of the installed software manually and add it to the Dockerfile.
Sometimes you want to run nodes inside the Docker and communicate with a ROS master outside of it. This can be done by adding the following environment variables to the docker-compose.yml
file
9 environment:
10 - ROS_MASTER_URI=http://localhost:11311
11 - ROS_HOSTNAME=localhost
where in this case localhost
stands for your local machine (the loop-back device 127.0.0.1
).
If the Docker should act as the master this might be more complicated and one might have to turn to virtual networking in Linux as described here.
You can test this by sourcing the environment, launching a roscore
on your local or remote computer, then launch the Docker source the local environment and see if you can see any topics inside $ rostopic list
. Then you can start publishing a topic $ rostopic pub /testing std_msgs/String "Testing..." -r 10
on one side (either Docker or host) and check if you receive the messages on the other side with $ rostopic echo /testing
.
You will find quite a few Docker configurations for ROS online, in particular this one for ROS2 is quite well made.
When working with larger software stacks tools like Docker-Compose and Docker Swarm might be useful for orchestration.