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