Our Dockerfiles by themselves aren’t all that useful since most of what they do is install fake packages.

The generation of the fake packages is the interesting part, I’m not sure how much I can share so I’ll describe it in high level terms. The entire process operates entirely within the realms of Debian packaging, nothing ROS specific.

When we want to build an image we declare its high level debian dependencies, typically this will be a set of ROS packages (e.g. ros-kinetic-ros-core) and some other libraries that we want to use with it. We then have a Python script which takes this list and traverses the dependency graph. As it traverses the graph it will start to prune off dependencies based off of certain criteria, some of this will be hard coded rules based on package names but mostly it’s automated heuristics. The main one is the one which eliminates packages based on their debian section. While all the ROS packages sit in the misc section (since bloom doesn’t know any better) the packages in the upstream Ubuntu repos are nicely split up which makes it easy to eliminate all the packages in the devel section or the graphics section. As we prune off packages we add them to a list of packages to “provide” in the metapackage we’re going to generate.

Along with this we also explicitly add certain non-dev dependencies to the images. For example we explicitly add all of the non-dev boost packages (which turn out to be not that big) to our images to make up for not having the boost-dev meta-package.

Here’s an example of the pruned graph for ros-kinetic-ros-core (nodes are only shown the first time they’re found in the graph):

*   113.5MB /   658.9MB   ros-kinetic-ros-core
*    31.9MB /    81.6MB     ros-kinetic-catkin
      0.0MB /    36.0MB       cmake
      0.0MB /     7.3MB       google-mock
      0.0MB /     0.0MB       libgtest-dev
*    30.0MB /    36.5MB       python-catkin-pkg
*    26.6MB /    33.1MB         python-dateutil
*    23.7MB /    30.2MB           python-six
*    23.6MB /    30.1MB             python
*    23.0MB /    29.5MB               python2.7
*     6.3MB /     6.3MB                 python2.7-minimal
*     2.7MB /     2.7MB                   libpython2.7-minimal
*     0.2MB /     0.2MB                   zlib1g
*    16.3MB /    22.8MB                 libpython2.7-stdlib
*     0.1MB /     0.1MB                   mime-support
*     0.1MB /     0.1MB                   libbz2-1.0
*     1.7MB /     1.7MB                   libdb5.3
*     0.4MB /     0.4MB                   libexpat1
*     0.1MB /     0.1MB                   libffi6
*     0.8MB /     0.8MB                   libncursesw5
*     0.5MB /     0.5MB                     libtinfo5
*     0.4MB /     6.9MB                   libreadline6
*     0.1MB /     6.6MB                     readline-common
      0.0MB /     6.5MB                       dpkg
*     0.9MB /     0.9MB                   libsqlite3-0
*     3.3MB /     3.3MB                   libssl1.0.0
*     0.0MB /     0.0MB               libpython-stdlib
*     2.7MB /     2.7MB           tzdata
*     2.9MB /     2.9MB         python-docutils
*     0.0MB /     0.0MB           python-roman
*     1.2MB /     1.2MB           docutils-common
*     0.1MB /     0.1MB             sgml-base
*     0.5MB /     0.5MB             xml-core
*     0.3MB /     0.3MB               sed
*     0.2MB /     0.2MB         python-pyparsing
*     0.2MB /     0.2MB         python-catkin-pkg-modules
*     0.3MB /     0.3MB       python-empy
*     1.0MB /     1.0MB       python-nose
*     0.4MB /     0.4MB         python-pkg-resources
      0.0MB /     0.1MB     ros-kinetic-cmake-modules
*    11.0MB /   385.4MB     ros-kinetic-common-msgs
*     4.9MB /   379.3MB       ros-kinetic-actionlib-msgs
      0.0MB /     0.3MB         ros-kinetic-message-generation
*     3.6MB /   377.7MB         ros-kinetic-message-runtime
*     2.1MB /   376.3MB           ros-kinetic-cpp-common
*     2.0MB /     2.0MB             libconsole-bridge0.2v5
*     2.0MB /     2.0MB               libstdc++6
*     0.1MB /     0.1MB                 gcc-5-base
      0.0MB /   308.0MB             libboost-all-dev
      0.0MB /    66.1MB             libconsole-bridge-dev
*     1.0MB /     1.0MB           ros-kinetic-genpy
*     0.6MB /     0.6MB             python-yaml
*     0.2MB /     0.2MB               libyaml-0-2
*     0.2MB /     0.2MB             ros-kinetic-genmsg
*     0.4MB /     0.4MB           ros-kinetic-roscpp-serialization
*     0.4MB /     0.4MB             ros-kinetic-roscpp-traits
*     0.3MB /     0.3MB               ros-kinetic-rostime
*     0.1MB /     0.1MB                 libboost-system1.58.0
*     1.1MB /     1.1MB         ros-kinetic-std-msgs
*     0.3MB /     0.3MB       ros-kinetic-diagnostic-msgs
*     1.2MB /     1.2MB       ros-kinetic-geometry-msgs
*     1.0MB /     1.0MB       ros-kinetic-nav-msgs
*     1.8MB /     1.8MB       ros-kinetic-sensor-msgs
*     0.2MB /     0.2MB       ros-kinetic-shape-msgs
*     0.1MB /     0.1MB       ros-kinetic-stereo-msgs
*     0.3MB /     0.3MB       ros-kinetic-trajectory-msgs
      0.0MB /     0.0MB         ros-kinetic-rosbag-migration-rule
*     1.1MB /     1.1MB       ros-kinetic-visualization-msgs
*     0.1MB /     0.1MB     ros-kinetic-gencpp
*     0.1MB /     0.1MB     ros-kinetic-geneus
      0.0MB /     0.1MB     ros-kinetic-genlisp
      0.0MB /     0.1MB     ros-kinetic-gennodejs
*     7.9MB /    31.9MB     ros-kinetic-ros
*     0.0MB /     0.2MB       ros-kinetic-mk
      0.0MB /     0.1MB         ros-kinetic-rosbuild
*     0.1MB /     0.1MB       ros-kinetic-rosbash
      0.0MB /     0.1MB       ros-kinetic-rosboost-cfg
*     0.2MB /    23.2MB       ros-kinetic-rosclean
*     0.1MB /    23.1MB         python-rospkg
*     0.1MB /    23.1MB           python-rospkg-modules
      0.0MB /    23.0MB             lsb-release
*     0.1MB /     0.1MB       ros-kinetic-roscreate
*     0.0MB /     0.0MB       ros-kinetic-roslang
*     7.5MB /     7.9MB       ros-kinetic-roslib
*     0.0MB /     0.0MB         ros-kinetic-ros-environment
*     7.0MB /     7.4MB         ros-kinetic-rospack
*     0.1MB /     0.1MB           libboost-filesystem1.58.0
*     0.5MB /     0.5MB           libboost-program-options1.58.0
*     3.5MB /     3.5MB           libpython2.7
*     0.1MB /     0.1MB           libtinyxml2.6.2v5
      0.0MB /     0.2MB           libtinyxml-dev
      0.0MB /     0.2MB           pkg-config
      0.0MB /     0.0MB           python-dev
*     2.4MB /     2.4MB           python-rosdep
*     2.1MB /     2.1MB             python-rosdistro
*     1.3MB /     1.3MB               ca-certificates
*     0.9MB /     0.9MB                 openssl
*     0.7MB /     0.7MB               python-rosdistro-modules
*     0.5MB /     0.5MB                 python-setuptools
      0.0MB /     0.1MB       ros-kinetic-rosmake
      0.0MB /     0.2MB       ros-kinetic-rosunit
*    62.5MB /   159.5MB     ros-kinetic-ros-comm
*    36.5MB /    68.0MB       ros-kinetic-message-filters
*    33.3MB /    64.7MB         ros-kinetic-rosconsole
*    30.5MB /    30.5MB           libboost-regex1.58.0
*    29.4MB /    29.4MB             libicu55
*     2.4MB /     6.2MB           liblog4cxx10v5
*     0.4MB /     4.1MB             libapr1
*     0.1MB /     3.8MB               libuuid1
      0.0MB /     3.7MB                 passwd
*     0.2MB /     0.2MB             libaprutil1
      0.0MB /     8.2MB           libapr1-dev
      0.0MB /    12.2MB           libaprutil1-dev
      0.0MB /     7.3MB           liblog4cxx10-dev
*     3.1MB /     3.1MB         ros-kinetic-roscpp
*     0.1MB /     0.1MB           libboost-chrono1.58.0
*     0.2MB /     0.2MB           libboost-thread1.58.0
*     0.2MB /     0.2MB           ros-kinetic-rosgraph-msgs
*     0.2MB /     0.2MB           ros-kinetic-xmlrpcpp
*    21.3MB /    21.5MB       ros-kinetic-rosbag
*     0.6MB /     0.8MB         ros-kinetic-rosbag-storage
      0.0MB /     0.1MB           libbz2-dev
*     0.2MB /     0.4MB           ros-kinetic-roslz4
*     0.1MB /     0.1MB             liblz4-1
      0.0MB /     0.2MB             liblz4-dev
*    18.1MB /    18.1MB         ros-kinetic-rospy
*    17.1MB /    17.1MB           python-numpy
*     0.5MB /     0.5MB             libblas3
*     0.0MB /     0.0MB               libblas-common
*     7.5MB /     7.5MB             liblapack3
*     1.5MB /     1.5MB               libgfortran3
*     0.3MB /     0.3MB                 libquadmath0
*     0.3MB /     0.3MB           ros-kinetic-rosgraph
*     0.0MB /     0.0MB             python-netifaces
*     0.2MB /     0.2MB         ros-kinetic-std-srvs
*     1.1MB /     1.1MB         ros-kinetic-topic-tools
*     3.9MB /     3.9MB       ros-kinetic-roslaunch
*     2.6MB /     2.6MB         python-paramiko
*     1.9MB /     1.9MB           python-crypto
*     0.5MB /     0.5MB             libgmp10
*     0.1MB /     0.1MB           python-ecdsa
*     0.4MB /     0.4MB         ros-kinetic-rosmaster
*     0.1MB /     0.1MB           python-defusedxml
*     0.1MB /     0.1MB         ros-kinetic-rosout
*     0.1MB /     0.1MB         ros-kinetic-rosparam
      0.0MB /    65.3MB       ros-kinetic-roslisp
*     0.1MB /     0.1MB       ros-kinetic-rosmsg
*     0.3MB /     0.3MB       ros-kinetic-rosnode
*     0.2MB /     0.2MB         ros-kinetic-rostopic
*     0.1MB /     0.1MB       ros-kinetic-rosservice
*     0.1MB /     0.1MB       ros-kinetic-rostest
*     0.2MB /     0.2MB       ros-kinetic-roswtf
*     0.0MB /     0.0MB     ros-kinetic-rosconsole-bridge
*     0.0MB /     0.0MB     ros-kinetic-roscpp-core