|
| 1 | +# syntax=docker/dockerfile:experimental |
| 2 | + |
| 3 | +# Use experimental buildkit for faster builds |
| 4 | +# https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md |
| 5 | +# Use `--progress=plain` to use plane stdout for docker build |
| 6 | +# |
| 7 | +# Example build command: |
| 8 | +# This determines which version of the ROS2 code base to pull |
| 9 | +# export ROS2_BRANCH=main |
| 10 | +# export DOCKER_BUILDKIT=1 |
| 11 | +# docker build \ |
| 12 | +# --tag nav2:source \ |
| 13 | +# --file source.Dockerfile ../ |
| 14 | +# |
| 15 | +# Use `--no-cache` to break the local docker build cache. |
| 16 | +# Use `--pull` to pull the latest parent image from the remote registry. |
| 17 | +# Use `--target=<stage_name>` to build stages not used for final stage. |
| 18 | +# |
| 19 | +# We're only building on top of a ros2 devel image to get the basics |
| 20 | +# prerequisites installed such as the apt source, rosdep, etc. We don't want to |
| 21 | +# actually use any of the ros release packages. Instead we are going to build |
| 22 | +# everything from source in one big workspace. |
| 23 | + |
| 24 | +ARG FROM_IMAGE=osrf/ros2:devel |
| 25 | +ARG UNDERLAY_WS=/opt/underlay_ws |
| 26 | +ARG OVERLAY_WS=/opt/overlay_ws |
| 27 | + |
| 28 | +# multi-stage for caching |
| 29 | +FROM $FROM_IMAGE AS cacher |
| 30 | + |
| 31 | +# clone ros2 source |
| 32 | +ARG ROS2_BRANCH=master |
| 33 | +ARG ROS2_REPO=https://github.com/ros2/ros2.git |
| 34 | +WORKDIR $ROS2_WS/src |
| 35 | +RUN git clone $ROS2_REPO -b $ROS2_BRANCH && \ |
| 36 | + vcs import ./ < ros2/ros2.repos && \ |
| 37 | + find ./ -name ".git" | xargs rm -rf |
| 38 | + |
| 39 | +# clone underlay source |
| 40 | +ARG UNDERLAY_WS |
| 41 | +WORKDIR $UNDERLAY_WS/src |
| 42 | +COPY ./tools/underlay.repos ../ |
| 43 | +RUN vcs import ./ < ../underlay.repos && \ |
| 44 | + find ./ -name ".git" | xargs rm -rf |
| 45 | + |
| 46 | +# copy overlay source |
| 47 | +ARG OVERLAY_WS |
| 48 | +WORKDIR $OVERLAY_WS/src |
| 49 | +COPY ./ ./ros-planning/navigation2 |
| 50 | +RUN colcon list --names-only | cat >> /opt/packages.txt |
| 51 | + |
| 52 | +# remove skiped packages |
| 53 | +WORKDIR /opt |
| 54 | +RUN find ./ \ |
| 55 | + -name "AMENT_IGNORE" -o \ |
| 56 | + -name "CATKIN_IGNORE" -o \ |
| 57 | + -name "COLCON_IGNORE" \ |
| 58 | + | xargs dirname | xargs rm -rf || true && \ |
| 59 | + colcon list --paths-only \ |
| 60 | + --packages-skip-up-to \ |
| 61 | + $(cat packages.txt | xargs) \ |
| 62 | + | xargs rm -rf |
| 63 | + |
| 64 | +# copy manifests for caching |
| 65 | +RUN mkdir -p /tmp/opt && \ |
| 66 | + find ./ -name "package.xml" | \ |
| 67 | + xargs cp --parents -t /tmp/opt |
| 68 | + |
| 69 | +# multi-stage for ros2 dependencies |
| 70 | +FROM $FROM_IMAGE AS ros2_depender |
| 71 | +ARG DEBIAN_FRONTEND=noninteractive |
| 72 | + |
| 73 | +# edit apt for caching |
| 74 | +RUN cp /etc/apt/apt.conf.d/docker-clean /etc/apt/ && \ |
| 75 | + echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' \ |
| 76 | + > /etc/apt/apt.conf.d/docker-clean |
| 77 | + |
| 78 | +# install packages |
| 79 | +RUN --mount=type=cache,target=/var/cache/apt \ |
| 80 | + --mount=type=cache,target=/var/lib/apt \ |
| 81 | + apt-get update && apt-get install -q -y \ |
| 82 | + ccache \ |
| 83 | + libasio-dev \ |
| 84 | + libtinyxml2-dev \ |
| 85 | + && rosdep update |
| 86 | + |
| 87 | +ENV ROS_VERSION=2 \ |
| 88 | + ROS_PYTHON_VERSION=3 |
| 89 | + |
| 90 | +# install ros2 dependencies |
| 91 | +WORKDIR $ROS2_WS |
| 92 | +COPY --from=cacher /tmp/$ROS2_WS ./ |
| 93 | +COPY ./tools/skip_keys.txt /tmp/ |
| 94 | +RUN --mount=type=cache,target=/var/cache/apt \ |
| 95 | + --mount=type=cache,target=/var/lib/apt \ |
| 96 | + apt-get update && rosdep install -q -y \ |
| 97 | + --from-paths src \ |
| 98 | + --ignore-src \ |
| 99 | + --skip-keys " \ |
| 100 | + $(cat /tmp/skip_keys.txt | xargs) \ |
| 101 | + " |
| 102 | + |
| 103 | +# multi-stage for building ros2 |
| 104 | +FROM ros2_depender AS ros2_builder |
| 105 | + |
| 106 | +# build ros2 source |
| 107 | +COPY --from=cacher $ROS2_WS ./ |
| 108 | +ARG ROS2_MIXINS="release ccache" |
| 109 | +RUN --mount=type=cache,target=/root/.ccache \ |
| 110 | + colcon build \ |
| 111 | + --symlink-install \ |
| 112 | + --mixin $ROS2_MIXINS |
| 113 | + |
| 114 | +# multi-stage for testing ros2 |
| 115 | +FROM ros2_builder AS ros2_tester |
| 116 | + |
| 117 | +# test overlay build |
| 118 | +ARG RUN_TESTS |
| 119 | +ARG FAIL_ON_TEST_FAILURE=True |
| 120 | +RUN if [ -n "$RUN_TESTS" ]; then \ |
| 121 | + . install/setup.sh && \ |
| 122 | + colcon test && \ |
| 123 | + colcon test-result \ |
| 124 | + || ([ -z "$FAIL_ON_TEST_FAILURE" ] || exit 1) \ |
| 125 | + fi |
| 126 | + |
| 127 | +# multi-stage for underlay dependencies |
| 128 | +FROM ros2_depender AS underlay_depender |
| 129 | + |
| 130 | +# copy manifests for caching |
| 131 | +COPY --from=cacher /tmp/$ROS2_WS $ROS2_WS |
| 132 | + |
| 133 | +# install underlay dependencies |
| 134 | +ARG UNDERLAY_WS |
| 135 | +WORKDIR $UNDERLAY_WS |
| 136 | +COPY --from=cacher /tmp/$UNDERLAY_WS ./ |
| 137 | +RUN --mount=type=cache,target=/var/cache/apt \ |
| 138 | + --mount=type=cache,target=/var/lib/apt \ |
| 139 | + apt-get update && rosdep install -q -y \ |
| 140 | + --from-paths src \ |
| 141 | + $ROS2_WS/src \ |
| 142 | + --ignore-src \ |
| 143 | + --skip-keys " \ |
| 144 | + $(cat /tmp/skip_keys.txt | xargs) \ |
| 145 | + " |
| 146 | + |
| 147 | +# multi-stage for building underlay |
| 148 | +FROM underlay_depender AS underlay_builder |
| 149 | + |
| 150 | +# copy workspace for caching |
| 151 | +COPY --from=ros2_builder $ROS2_WS $ROS2_WS |
| 152 | + |
| 153 | +# build underlay source |
| 154 | +COPY --from=cacher $UNDERLAY_WS ./ |
| 155 | +ARG UNDERLAY_MIXINS="release ccache" |
| 156 | +RUN --mount=type=cache,target=/root/.ccache \ |
| 157 | + . $ROS2_WS/install/setup.sh && \ |
| 158 | + colcon build \ |
| 159 | + --symlink-install \ |
| 160 | + --mixin $UNDERLAY_MIXINS |
| 161 | + |
| 162 | +# multi-stage for testing underlay |
| 163 | +FROM underlay_builder AS underlay_tester |
| 164 | + |
| 165 | +# test overlay build |
| 166 | +ARG RUN_TESTS |
| 167 | +ARG FAIL_ON_TEST_FAILURE=True |
| 168 | +RUN if [ -n "$RUN_TESTS" ]; then \ |
| 169 | + . install/setup.sh && \ |
| 170 | + colcon test && \ |
| 171 | + colcon test-result \ |
| 172 | + || ([ -z "$FAIL_ON_TEST_FAILURE" ] || exit 1) \ |
| 173 | + fi |
| 174 | + |
| 175 | +# multi-stage for overlay dependencies |
| 176 | +FROM underlay_depender AS overlay_depender |
| 177 | + |
| 178 | +# copy manifests for caching |
| 179 | +COPY --from=cacher /tmp/$ROS2_WS $ROS2_WS |
| 180 | +COPY --from=cacher /tmp/$UNDERLAY_WS $UNDERLAY_WS |
| 181 | + |
| 182 | +# install overlay dependencies |
| 183 | +ARG OVERLAY_WS |
| 184 | +WORKDIR $OVERLAY_WS |
| 185 | +COPY --from=cacher /tmp/$OVERLAY_WS ./ |
| 186 | +RUN --mount=type=cache,target=/var/cache/apt \ |
| 187 | + --mount=type=cache,target=/var/lib/apt \ |
| 188 | + apt-get update && rosdep install -q -y \ |
| 189 | + --from-paths src \ |
| 190 | + $ROS2_WS/src \ |
| 191 | + $UNDERLAY_WS/src \ |
| 192 | + --ignore-src \ |
| 193 | + --skip-keys " \ |
| 194 | + $(cat /tmp/skip_keys.txt | xargs) \ |
| 195 | + " |
| 196 | + |
| 197 | +# multi-stage for building overlay |
| 198 | +FROM overlay_depender AS overlay_builder |
| 199 | + |
| 200 | +# copy workspace for caching |
| 201 | +COPY --from=ros2_builder $ROS2_WS $ROS2_WS |
| 202 | +COPY --from=underlay_builder $UNDERLAY_WS $UNDERLAY_WS |
| 203 | + |
| 204 | +# build overlay source |
| 205 | +COPY --from=cacher $OVERLAY_WS ./ |
| 206 | +ARG OVERLAY_MIXINS="release ccache" |
| 207 | +RUN --mount=type=cache,target=/root/.ccache \ |
| 208 | + . $UNDERLAY_WS/install/setup.sh && \ |
| 209 | + colcon build \ |
| 210 | + --symlink-install \ |
| 211 | + --mixin $OVERLAY_MIXINS |
| 212 | + |
| 213 | +# multi-stage for testing overlay |
| 214 | +FROM overlay_builder AS overlay_tester |
| 215 | + |
| 216 | +# test overlay build |
| 217 | +ARG RUN_TESTS |
| 218 | +ARG FAIL_ON_TEST_FAILURE=True |
| 219 | +RUN if [ -n "$RUN_TESTS" ]; then \ |
| 220 | + . install/setup.sh && \ |
| 221 | + colcon test && \ |
| 222 | + colcon test-result \ |
| 223 | + || ([ -z "$FAIL_ON_TEST_FAILURE" ] || exit 1) \ |
| 224 | + fi |
| 225 | + |
| 226 | +# multi-stage for testing workspaces |
| 227 | +FROM overlay_builder AS workspaces_tester |
| 228 | + |
| 229 | +# copy workspace test results |
| 230 | +COPY --from=ros2_tester $ROS2_WS/log $ROS2_WS/log |
| 231 | +COPY --from=underlay_tester $UNDERLAY_WS/log $UNDERLAY_WS/log |
| 232 | +COPY --from=overlay_tester $OVERLAY_WS/log $OVERLAY_WS/log |
| 233 | + |
| 234 | +# multi-stage for shipping overlay |
| 235 | +FROM overlay_builder AS overlay_shipper |
| 236 | + |
| 237 | +# restore apt for docker |
| 238 | +RUN mv /etc/apt/docker-clean /etc/apt/apt.conf.d/ && \ |
| 239 | + rm -rf /var/lib/apt/lists/ |
| 240 | + |
| 241 | +# source overlay from entrypoint |
| 242 | +ENV UNDERLAY_WS $UNDERLAY_WS |
| 243 | +ENV OVERLAY_WS $OVERLAY_WS |
| 244 | +RUN sed --in-place \ |
| 245 | + 's|^source .*|source "$OVERLAY_WS/install/setup.bash"|' \ |
| 246 | + /ros_entrypoint.sh |
0 commit comments