-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[ROS] Add Official Docker image for ROS2 #1381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
8e1766c
Start docs for ROS 2 by duplicating those from ROS 1
ruffsl 5fb5991
Update lichening information to reflect ROS 2
ruffsl d70ba62
Update intro
ruffsl f7bd0f2
Update example dockerfile and compose file
ruffsl 66a3f10
Remove redundant walk through and skip to compose
ruffsl 725cd24
Cleanup dockerfile example
ruffsl 36501f9
Make dockerfile example a multistage build
ruffsl 92406af
Create an install and build example
ruffsl bdd6d7d
Update body and links
ruffsl a7ed044
Update logo
ruffsl 702f14d
Add security example
ruffsl 3a66e1a
Add warnings about networking with ROS2/DDS
ruffsl db9791a
Fix compose file
ruffsl c1c457d
Fix Spelling
ruffsl b03d7d9
Remove duplicate files before merge
ruffsl 40f09e8
Remove duplicate files before merge
ruffsl eb9d43c
Move changes for merge
ruffsl f4edbfb
Rewording to just reference latest ros release
ruffsl 199e0a5
Fix markdown for CI
ruffsl 347e32d
Provide sros2 cli in example and fix keystore permissions
ruffsl bbeff28
Fix Spelling
ruffsl 332a6e8
Update example to use latest LTS tag
ruffsl 3d1f775
Hold off on sros example
ruffsl 8398e71
Update docs link to point to index.ros.org
ruffsl edb64bb
Merge branch 'master' into ros2
ruffsl a62f77d
Update Dockerfile build example
ruffsl e71b10d
Add links to target support reps
ruffsl 1a14579
Update metrics
ruffsl a1c20bd
Add minimal ros1_bridge example
ruffsl 32e1ffe
Fix Formatting
ruffsl 6d09179
Update More Resources
ruffsl 2cd312f
Dont split up ros version tokens for SEO
ruffsl 966f6ae
Keep ros org landing page as main link
ruffsl f685e28
Update size given no-install-recommends changes
ruffsl 379df84
Spell check
ruffsl 66047eb
Update examples
ruffsl b4f8a13
Fix logging for python node
ruffsl 23bf362
Link external license resources like other images
ruffsl cc17087
Stage changes to build example
ruffsl 2316f47
Update example
ruffsl 522d608
Add links to tools
ruffsl 50a2c27
Link to relevent reps on variants
ruffsl dd187b9
Simplify example
ruffsl 957be64
Update explanation of example
ruffsl 2f8fd67
Fix markdown linter
ruffsl 38e4286
Update tags to foxy and noetic
ruffsl c305016
Correct vcstool link
ruffsl cf84c67
Nit fix grammar
ruffsl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The Robot Operating System (ROS) is an open source project for building robot applications. |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,265 @@ | ||
# What is [ROS 2](https://index.ros.org/doc/ros2)? | ||
|
||
The Robot Operating System (ROS) is a set of software libraries and tools that help you build robot applications. From drivers to state-of-the-art algorithms, and with powerful developer tools, ROS has what you need for your next robotics project. And it's all open source. ROS 2 is the next-generation ROS: building upon modern middleware for decentralized discovery, message serialization, and secure transport with quality of service enabling high performance, low latency, language agnostic distributed computing for robotic systems. | ||
|
||
> [wikipedia.org/wiki/Robot_Operating_System](https://en.wikipedia.org/wiki/Robot_Operating_System) | ||
|
||
[%%LOGO%%](https://index.ros.org/doc/ros2) | ||
ruffsl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# How to use this image | ||
|
||
## Creating a `Dockerfile` to install ROS 2 packages | ||
|
||
To create your own ROS 2 docker images and install custom packages, here's a simple example of installing the C++ and Python client library demos using the official released Debian packages via apt-get. | ||
|
||
```dockerfile | ||
FROM %%IMAGE%%:ros-core | ||
|
||
# install ros packages for installed release | ||
RUN apt-get update && apt-get install -y \ | ||
ros-${ROS_DISTRO}-demo-nodes-cpp \ | ||
ros-${ROS_DISTRO}-demo-nodes-py && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# run ros package launch file | ||
CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] | ||
``` | ||
|
||
Note: all ROS 2 images include a default entrypoint that sources the ROS environment setup before exiting the configured command, in this case the demo packages launch file. You can then build and run the Docker image like so: | ||
|
||
```console | ||
$ docker build -t my/ros2:app . | ||
$ docker run -it --rm my/ros2:app | ||
[INFO] [launch]: process[talker-1]: started with pid [813] | ||
[INFO] [launch]: process[listener-2]: started with pid [814] | ||
[INFO] [talker]: Publishing: 'Hello World: 1' | ||
[INFO] [listener]: I heard: [Hello World: 1] | ||
[INFO] [talker]: Publishing: 'Hello World: 2' | ||
[INFO] [listener]: I heard: [Hello World: 2] | ||
... | ||
``` | ||
|
||
## Creating a `Dockerfile` to build ROS 2 packages | ||
|
||
To create your own ROS 2 docker images and build custom packages, here's a simple example of installing a package's build dependencies, compiling it from source, and installing the resulting build artifacts into a final multi-stage image layer. | ||
|
||
```dockerfile | ||
FROM %%IMAGE%%:ros-base | ||
|
||
# install ros build tools | ||
RUN apt-get update && apt-get install -y \ | ||
python3-colcon-common-extensions && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# clone ros package repo | ||
ENV ROS2_WS /opt/ros2_ws | ||
RUN mkdir -p $ROS2_WS/src | ||
WORKDIR $ROS2_WS | ||
RUN git -C src clone \ | ||
-b $ROS_DISTRO \ | ||
https://github.com/ros2/demos.git | ||
|
||
# install ros package dependencies | ||
RUN apt-get update && \ | ||
rosdep update && \ | ||
rosdep install -y \ | ||
--from-paths \ | ||
src/demos/demo_nodes_cpp \ | ||
--ignore-src && \ | ||
rm -rf /var/lib/apt/lists/* | ||
|
||
# build ros package source | ||
RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ | ||
colcon build \ | ||
--packages-select \ | ||
demo_nodes_cpp \ | ||
--cmake-args \ | ||
-DCMAKE_BUILD_TYPE=Release | ||
|
||
# copy ros package install via multi-stage | ||
FROM %%IMAGE%%:ros-core | ||
ENV ROS2_WS /opt/ros2_ws | ||
COPY --from=0 $ROS2_WS/install $ROS2_WS/install | ||
ruffsl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# source ros package from entrypoint | ||
RUN sed --in-place --expression \ | ||
'$isource "$ROS2_WS/install/setup.bash"' \ | ||
/ros2_entrypoint.sh | ||
|
||
# run ros package launch file | ||
CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"] | ||
``` | ||
|
||
Note: `--from-paths` and `--packages-select` are set here as so to only install the dependencies and build for the `demo_nodes_cpp` package, one among many in the demo git repo that was cloned. To install the dependencies and build all the packages in the source workspace, merely change the scope by setting `--from-paths src/` and dropping the `--packages-select` arguments. | ||
|
||
``` | ||
REPOSITORY TAG IMAGE ID CREATED SIZE | ||
my/ros2 app-multi-stage 66c8112b2fb6 4 seconds ago 775MB | ||
my/ros2 app-single-stage 6b500239d0d6 2 minutes ago 797MB | ||
``` | ||
|
||
For this particular package, using a multi-stage build didn't shrink the final image by much, but for more complex applications, segmenting build setup from the runtime can help keep image sizes down. Additionally, doing so can also prepare you for releasing your package to the community, helping to reconcile dependency discrepancies you may have otherwise forgotten to declare in your `package.xml` manifest. | ||
|
||
## Deployment use cases | ||
|
||
This dockerized image of ROS 2 is intended to provide a simplified and consistent platform to build and deploy distributed robotic applications. Built from the [official Ubuntu image](https://hub.docker.com/_/ubuntu/) and ROS's official Debian packages, it includes recent supported releases for quick access and download. This provides roboticists in research and industry with an easy way to develop, reuse and ship software for autonomous actions and task planning, control dynamics, localization and mapping, swarm behavior, as well as general system integration. | ||
|
||
Developing such complex systems with cutting edge implementations of newly published algorithms remains challenging, as repeatability and reproducibility of robotic software can fall to the wayside in the race to innovate. With the added difficulty in coding, tuning and deploying multiple software components that span across many engineering disciplines, a more collaborative approach becomes attractive. However, the technical difficulties in sharing and maintaining a collection of software over multiple robots and platforms has for a while exceeded time and effort than many smaller labs and businesses could afford. | ||
|
||
With the advancements and standardization of software containers, roboticists are primed to acquire a host of improved developer tooling for building and shipping software. To help alleviate the growing pains and technical challenges of adopting new practices, we have focused on providing an official resource for using ROS with these new technologies. | ||
|
||
## Deployment suggestions | ||
|
||
The available tags include supported distros along with a hierarchy tags based off the most common meta-package dependencies, designed to have a small footprint and simple configuration: | ||
|
||
- `ros-core`: barebone ROS 2 install | ||
- `ros-base`: basic tools and libraries (also tagged with distro name with LTS version as `latest`) | ||
|
||
The rest of the common meta-packages such as `desktop` and `ros1-bridge` are hosted on automatic build repos under OSRF's Docker Hub profile [here](https://hub.docker.com/r/osrf/ros2/). These meta-packages include graphical dependencies and hook a host of other large packages such as X11, X server, etc. So in the interest of keep the official images lean and secure, the desktop packages are just be hosted with OSRF's profile. | ||
|
||
### Volumes | ||
|
||
ROS uses the `~/.ros/` directory for storing logs, and debugging info. If you wish to persist these files beyond the lifecycle of the containers which produced them, the `~/.ros/` folder can be mounted to an external volume on the host, or a derived image can specify volumes to be managed by the Docker engine. By default, the container runs as the `root` user, so `/root/.ros/` would be the full path to these files. | ||
|
||
For example, if one wishes to use their own `.ros` folder that already resides in their local home directory, with a username of `ubuntu`, we can simple launch the container with an additional volume argument: | ||
|
||
```console | ||
$ docker run -v "/home/ubuntu/.ros/:/root/.ros/" %%IMAGE%% | ||
``` | ||
|
||
### Devices | ||
|
||
Some application may require device access for acquiring images from connected cameras, control input from human interface device, or GPUS for hardware acceleration. This can be done using the [`--device`](https://docs.docker.com/reference/run/) run argument to mount the device inside the container, providing processes inside hardware access. | ||
|
||
### Networks | ||
|
||
ROS 2 allows for peer-to-peer networking of processes (potentially distributed across machines) that are loosely coupled using the ROS communication infrastructure. ROS implements several different styles of communication, including synchronous RPC-style communication over services, asynchronous streaming of typed data over topics, combinations of both prior via request/reply and status/feedback over actions, and run-time settings via configuration over parameters. To abide by the best practice of [one process per container](https://docs.docker.com/articles/dockerfile_best-practices/), Docker networks can be used to string together several running ROS processes. For further details see the Deployment example further below. | ||
|
||
Alternatively, more permissive network setting can be use to share all host network interfaces with the container, such as [`host` network driver](https://docs.docker.com/network/host/), simplifying connectivity with external network participants. Be aware however that this removes the networking namespace separation between containers, and can affect the ability of DDS participants communicate between containers, as documented [here](https://community.rti.com/kb/how-use-rti-connext-dds-communicate-across-docker-containers-using-host-driver). | ||
|
||
## Deployment example | ||
|
||
### Docker Compose | ||
|
||
In this example we'll demonstrate using [`docker-compose`](https://docs.docker.com/compose/) to spawn a pair of message publisher and subscriber nodes in separate containers connected through shared software defined network. | ||
|
||
> Create the directory `~/ros2_demos` and add the first `Dockerfile` example from above. In the same directory, also create file `docker-compose.yml` with the following that runs a C++ publisher with a Python subscriber: | ||
|
||
```yaml | ||
version: '3' | ||
|
||
services: | ||
talker: | ||
build: ./Dockerfile | ||
command: ros2 run demo_nodes_cpp talker | ||
|
||
listener: | ||
build: ./Dockerfile | ||
command: ros2 run demo_nodes_py listener | ||
``` | ||
|
||
> Use docker-compose inside the same directory to launch our ROS nodes. Given the containers created derive from the same docker compose project, they will coexist on shared project network: | ||
|
||
```console | ||
$ docker-compose up -d | ||
``` | ||
|
||
> Notice that a new network named `ros2_demos` has been created, as can be shown further with: | ||
ruffsl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```console | ||
$ docker network inspect ros2_demos | ||
``` | ||
|
||
> We can monitor the logged output of each container, such as the listener node like so: | ||
|
||
```console | ||
$ docker-compose logs listener | ||
``` | ||
|
||
> Finally, we can stop and remove all the relevant containers using docker-compose from the same directory: | ||
|
||
```console | ||
$ docker-compose stop | ||
$ docker-compose rm | ||
``` | ||
|
||
> Note: the auto-generated network, `ros2_demos`, will persist until you explicitly remove it using `docker-compose down`. | ||
|
||
|
||
### Securing ROS 2 | ||
|
||
Lets build upon the example above by adding authenticated encryption to the message transport. This is done by leveraging [Secure DDS](https://www.omg.org/spec/DDS-SECURITY). We'll use the same ROS 2 docker image to bootstrap the PKI, CAs, and Digitally Signed files. | ||
|
||
> Create a script at `~/ros2_demos/keystore/bootstrap_keystore.bash` to bootstrap a keystore and add entries for each node: | ||
|
||
``` shell | ||
#!/usr/bin/env bash | ||
# Bootstrap ROS 2 keystore | ||
ros2 security create_keystore ./ | ||
ros2 security create_key ./ talker | ||
ros2 security create_key ./ listener | ||
ruffsl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
> Create a enforcement file at `~/ros2_demos/config.env` to configure ROS 2 Security: | ||
|
||
|
||
``` shell | ||
# Configure ROS 2 Security | ||
ROS_SECURITY_NODE_DIRECTORY=/keystore | ||
ROS_SECURITY_STRATEGY=Enforce | ||
ROS_SECURITY_ENABLE=true | ||
ROS_DOMAIN_ID=0 | ||
``` | ||
|
||
> Use a temporary container to run the keystore bootstrapping script in the keystore directory: | ||
|
||
|
||
```console | ||
$ docker run -it --rm \ | ||
--env-file ./config.env \ | ||
--volume ./keystore:/keystore:rw \ | ||
--workdir /keystore \ | ||
ros2 bash bootstrap_keystore.bash | ||
ruffsl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
> Now modify the original `docker-compose.yml` to use the configured environment and respective keystore entries: | ||
|
||
```yaml | ||
version: '3' | ||
|
||
services: | ||
talker: | ||
build: ./Dockerfile | ||
environment: | ||
- ./config.env | ||
volumes: | ||
- ./keystore/talker:/keystore:ro | ||
command: ros2 run demo_nodes_cpp talker | ||
|
||
listener: | ||
build: ./Dockerfile | ||
environment: | ||
- ./config.env | ||
volumes: | ||
- ./keystore/listener:/keystore:ro | ||
command: ros2 run demo_nodes_py listener | ||
``` | ||
|
||
> Now simply startup docker-compose as before: | ||
|
||
``` command | ||
$ docker-compose up | ||
``` | ||
|
||
Note: So far this has only added authenticated encryption, i.e. only participants with public certificates signed by a trusted CA may join the domain. To enable access control within the secure domain, i.e. restrict which and how topics may be used by participants, more such details can be found [here](https://github.com/ros2/sros2/). | ||
|
||
# More Resources | ||
|
||
[ROS.org](http://www.ros.org/): Main ROS website | ||
[Docs](https://docs.ros2.org/): Core Documentation | ||
ruffsl marked this conversation as resolved.
Show resolved
Hide resolved
|
||
[Index](https://index.ros.org/doc/ros2/): Package Index | ||
[Design](https://design.ros2.org/): Design Articles | ||
[ROS Answers](https://answers.ros.org/questions/): Ask questions. Get answers | ||
[Forums](https://discourse.ros.org/): Hear the latest discussions | ||
[Blog](http://www.ros.org/news/): Stay up-to-date | ||
[OSRF](https://www.osrfoundation.org/): Open Source Robotics Foundation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
https://github.com/osrf/docker_images |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
The core of ROS 2 is licensed under the Apache License 2.0. This is a very permissive open license that allows for modification, distribution, commercial use, patent use, and private use in open and closed source products. You can find more about the license from the [Apache License](https://www.apache.org/licenses) website or Opensource.org [Apache License 2.0](https://opensource.org/licenses/Apache-2.0) page. | ||
|
||
While the core parts of ROS 2 are licensed under the Apache 2.0 license, other licenses are commonly used in the community packages, such as the [BSD 3-Clause](https://opensource.org/licenses/BSD-3-Clause) license, the [GPL](https://opensource.org/licenses/gpl-license) license, the [MIT](https://opensource.org/licenses/MIT) license, and even proprietary licenses. Each package in the ROS ecosystem is required to specify a license, so that it is easy for you to quickly identify if a package will meet your licensing needs. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[the Open Source Robotics Foundation](%%GITHUB-REPO%%) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.