[ros-users] [Discourse.ros.org] [General] Announcing Official Docker Images for ROS2

ruffsl via Discourse.ros.org ros.discourse at gmail.com
Wed Jan 9 04:11:55 UTC 2019



As the readme for library's repo docs hasn't yet updated, I'll include some relevant excerpts from the respective PR that reflect some notable changes.

---

## Creating a `Dockerfile` to install ROS packages

To create your own ROS docker images and install custom packages, here's a simple example of installing the C++, Python client library demos and security CLI using the official released Debian packages via apt-get.

```dockerfile
FROM ros:crystal

# 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 \
      ros-${ROS_DISTRO}-sros2 && \
    rm -rf /var/lib/apt/lists/*

# run ros package launch file
CMD ["ros2", "launch", "demo_nodes_cpp", "talker_listener.launch.py"]
```

Note: all ROS 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/ros:app .
$ docker run -it --rm my/ros: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 packages

To create your own ROS 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 ros:crystal-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 ROS_WS /opt/ros_ws
RUN mkdir -p $ROS_WS/src
WORKDIR $ROS_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 ros:crystal-ros-core
ENV ROS_WS /opt/ros_ws
COPY --from=0  $ROS_WS/install $ROS_WS/install

# source ros package from entrypoint
RUN sed --in-place --expression \
      '$isource "$ROS_WS/install/setup.bash"' \
      /ros_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/ros        app-multi-stage     66c8112b2fb6    4 seconds ago   775MB
	my/ros        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 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 `~/ros_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 `ros_demos` has been created, as can be shown further with:

```console
$ docker network inspect ros_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, `ros_demos`, will persist until you explicitly remove it using `docker-compose down`.

### Networks

For those who use more permissive network setting to share all host network interfaces with the container, such as [`host` network driver](https://docs.docker.com/network/host/); Be aware that this removes the networking namespace separation between containers, and can affect the ability of DDS participants communicate between containers, as exampled [here](https://community.rti.com/kb/how-use-rti-connext-dds-communicate-across-docker-containers-using-host-driver).

Additionally, if shared memory transport between ROS nodes within separate containers is desired, shared memory access must be expressly conferred, as exampled [here](https://community.rti.com/kb/communicate-two-docker-containers-using-rti-connext-dds-and-shared-memory).





---
[Visit Topic](https://discourse.ros.org/t/announcing-official-docker-images-for-ros2/7381/2) or reply to this email to respond.




More information about the ros-users mailing list