Skip to content

Commit 5b77695

Browse files
committed
Moved Mavros build to a build stage, which hopefully will get cached.
1 parent 44a211b commit 5b77695

File tree

1 file changed

+101
-43
lines changed

1 file changed

+101
-43
lines changed

.docker/Dockerfile

+101-43
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,102 @@
11
ARG ROS_DISTRO=rolling
2-
FROM ros:$ROS_DISTRO-ros-base AS ci
2+
FROM ros:$ROS_DISTRO-ros-base AS base
3+
4+
# Create the non-root user early because both "mavros" and "robot"
5+
# stages depend its existence
6+
RUN apt-get -q update \
7+
&& apt-get -q -y upgrade \
8+
&& apt-get -q install --no-install-recommends -y \
9+
git \
10+
gosu \
11+
sudo \
12+
&& apt-get autoremove -y \
13+
&& apt-get clean -y \
14+
&& rm -rf /var/lib/apt/lists/*
15+
16+
# Ubuntu 24.04 "Noble", which is used as the base image for
17+
# jazzy and rolling images, now includes a user "ubuntu" at UID 1000
18+
ARG USERNAME=ubuntu
19+
ARG USER_UID=1000
20+
ARG USER_GID=$USER_UID
21+
22+
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
23+
&& chmod 0440 /etc/sudoers.d/$USERNAME \
24+
&& usermod -a -G dialout $USERNAME \
25+
&& echo "source /usr/share/bash-completion/completions/git" >> /home/$USERNAME/.bashrc
26+
27+
ENV DEBIAN_FRONTEND=noninteractive
28+
ENV USER=$USERNAME
29+
30+
# This needs to be defined in a shared stage so it's available in both "mavros" and "robot"
31+
ENV MAVROS_WORKSPACE=/home/$USERNAME/ws_mavros
32+
33+
#== Build Mavros/Mavlink from source in its own workspace.
34+
# Extend that workspace into the "blue" workspace
35+
#
36+
FROM base AS mavros
337

438
ENV DEBIAN_FRONTEND=noninteractive
39+
USER $USERNAME
40+
41+
WORKDIR $MAVROS_WORKSPACE/src
42+
43+
# As a reminder to self. git clone by itself will not break cache
44+
# when the repo changes. To rebuild mavros from the latest, you
45+
# must "docker build --no-cache" to force a rebuild
46+
ARG MAVROS_RELEASE=ros2
47+
ARG MAVLINK_RELEASE=release/rolling/mavlink
48+
RUN git clone --depth 1 -b ${MAVROS_RELEASE} https://github.com/mavlink/mavros.git
49+
RUN git clone --depth 1 --recursive -b ${MAVLINK_RELEASE} https://github.com/mavlink/mavlink-gbp-release.git mavlink
50+
# Fix two issues currently in mavros/ros2
51+
# - mavgen uses future.standard_library for backwards compatibility with Python2;
52+
# However, this caused issues with Python 3.12 installed in "noble".
53+
# Comment those lines out in mavlink.
54+
#
55+
# - Fix linkage for yaml-cpp in mavros_extra_plugins
56+
RUN sed -i -e 's/^from future import standard_library/#from future import standard_library/' \
57+
-e 's/standard_library.install_aliases()/#standard_library.install_aliases()/' \
58+
mavlink/pymavlink/generator/mavgen.py && \
59+
sed -i -e 's/^# find_package(yaml_cpp REQUIRED)/find_package(yaml-cpp REQUIRED)/' \
60+
-e '/^ament_target_dependencies(mavros_extras_plugins$/i target_link_libraries(mavros_extras_plugins yaml-cpp::yaml-cpp)' \
61+
-e '/^ament_target_dependencies(mavros_extras$/i target_link_libraries(mavros_extras yaml-cpp::yaml-cpp)' \
62+
mavros/mavros_extras/CMakeLists.txt
63+
64+
WORKDIR $MAVROS_WORKSPACE
65+
USER root
66+
RUN apt-get -q update \
67+
&& apt-get -q -y upgrade \
68+
&& gosu $USERNAME rosdep update \
69+
&& gosu $USERNAME rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} \
70+
&& apt-get autoremove -y \
71+
&& apt-get clean -y \
72+
&& rm -rf /var/lib/apt/lists/*
73+
USER $USERNAME
74+
75+
# Build Mavros workspace
76+
RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" \
77+
&& colcon build \
78+
&& rm -rf $MAVROS_WORKSPACE/build
79+
80+
# == "Standard" Blue Docker image proceeds from here
81+
#
82+
FROM base AS ci
83+
84+
ENV DEBIAN_FRONTEND=noninteractive
85+
USER root
586

687
WORKDIR /root/ws_blue
788
COPY . src/blue
889

990
# Install apt packages needed for CI
91+
#
92+
# Explicitly uninstall and block mavros and mavlink packages from APT
93+
# this will trigger an error if rosdep attempts to install mavros
94+
# from APT rather than using the version in $MAVROS_WORKSPACE
1095
RUN apt-get -q update \
1196
&& apt-get -q -y upgrade \
97+
&& apt-get remove -y "*mavros*" "*mavlink*" \
98+
&& apt-mark hold "*mavros*" "*mavlink*" \
1299
&& apt-get -q install --no-install-recommends -y \
13-
git \
14-
sudo \
15100
clang \
16101
clang-format-14 \
17102
clang-tidy \
@@ -27,12 +112,17 @@ RUN apt-get -q update \
27112
&& apt-get clean -y \
28113
&& rm -rf /var/lib/apt/lists/*
29114

30-
# Install all ROS dependencies for _just_ blue
31-
# (we have not imported other repos from .repos files)
115+
# As it's a dependency for blue, copy Mavros from its build stage
116+
COPY --from=mavros --chown=$USERNAME:$USERNAME $MAVROS_WORKSPACE $MAVROS_WORKSPACE
117+
118+
# Install all ROS dependencies for _just_ blue (and mavros)
119+
# (we have not imported the other repos from blue.repos files)
32120
RUN apt-get -q update \
33121
&& apt-get -q -y upgrade \
34122
&& rosdep update \
35-
&& rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} --as-root=apt:false \
123+
&& . "${MAVROS_WORKSPACE}/install/setup.sh" \
124+
&& rosdep install -y --from-paths ${MAVROS_WORKSPACE}/src --ignore-src --rosdistro ${ROS_DISTRO} \
125+
&& rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} \
36126
&& rm -rf src \
37127
&& apt-get autoremove -y \
38128
&& apt-get clean -y \
@@ -48,23 +138,8 @@ RUN apt-get -q update \
48138
#
49139
FROM ci AS robot
50140

51-
#
52-
# Ubuntu 24.04 "Noble", which is used as the base image for
53-
# jazzy and rolling images, now includes a user "ubuntu" at UID 1000
54-
ARG USERNAME=ubuntu
55-
ARG USER_UID=1000
56-
ARG USER_GID=$USER_UID
57-
58-
RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
59-
&& chmod 0440 /etc/sudoers.d/$USERNAME \
60-
&& usermod -a -G dialout $USERNAME \
61-
&& echo "source /usr/share/bash-completion/completions/git" >> /home/$USERNAME/.bashrc
62-
63-
ENV DEBIAN_FRONTEND=noninteractive
64-
65141
# Switch to the non-root user for the rest of the installation
66142
USER $USERNAME
67-
ENV USER=$USERNAME
68143

69144
# Python in Ubuntu is now marked as a "Externally managed environment",
70145
# Per best practice, create a venv for local python packages
@@ -108,41 +183,23 @@ RUN sudo apt-get -q update \
108183
&& sudo apt-get clean -y \
109184
&& sudo rm -rf /var/lib/apt/lists/*
110185

111-
# Manually install MAVROS from source in the ws_blue/ workspace
112-
WORKDIR $USER_WORKSPACE/src/
113-
ARG MAVROS_RELEASE=ros2
114-
ARG MAVLINK_RELEASE=release/rolling/mavlink
115-
RUN git clone --depth 1 -b ${MAVROS_RELEASE} https://github.com/mavlink/mavros.git
116-
RUN git clone --depth 1 --recursive -b ${MAVLINK_RELEASE} https://github.com/mavlink/mavlink-gbp-release.git mavlink
117-
# - mavgen uses future.standard_library for backwards compatibility with Python2;
118-
# However, this caused issues with Python 3.12 installed in "noble".
119-
# Comment those lines out in mavlink.
120-
#
121-
# - Fix linkage for yaml-cpp in mavros_extra_plugins
122-
RUN sed -i -e 's/^from future import standard_library/#from future import standard_library/' \
123-
-e 's/standard_library.install_aliases()/#standard_library.install_aliases()/' \
124-
mavlink/pymavlink/generator/mavgen.py && \
125-
sed -i -e 's/^# find_package(yaml_cpp REQUIRED)/find_package(yaml-cpp REQUIRED)/' \
126-
-e '/^ament_target_dependencies(mavros_extras_plugins$/i target_link_libraries(mavros_extras_plugins yaml-cpp::yaml-cpp)' \
127-
-e '/^ament_target_dependencies(mavros_extras$/i target_link_libraries(mavros_extras yaml-cpp::yaml-cpp)' \
128-
mavros/mavros_extras/CMakeLists.txt
129-
130186
WORKDIR $USER_WORKSPACE
131187
RUN sudo apt-get -q update \
132188
&& sudo apt-get -q -y upgrade \
133189
&& vcs import src < src/blue/blue.repos \
134190
&& rosdep update \
191+
&& . "${MAVROS_WORKSPACE}/install/setup.sh" \
192+
&& rosdep install -y --from-paths ${MAVROS_WORKSPACE}/src --ignore-src --rosdistro ${ROS_DISTRO} \
135193
&& rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} \
136194
&& sudo apt-get autoremove -y \
137195
&& sudo apt-get clean -y \
138196
&& sudo rm -rf /var/lib/apt/lists/*
139197

140198
# Actually build workspace
141-
RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" \
199+
RUN . "${MAVROS_WORKSPACE}/install/setup.sh" \
142200
&& colcon build
143201

144202
RUN echo "source ${USER_WORKSPACE}/install/setup.bash" >> /home/$USERNAME/.bashrc \
145-
&& echo "source /opt/ros/${ROS_DISTRO}/setup.bash" >> /home/$USERNAME/.bashrc \
146203
&& echo "source $VIRTUAL_ENV/bin/activate" >> /home/$USERNAME/.bashrc \
147204
&& echo "\n# Ensure colcon is run in the venv\nalias colcon='python3 -m colcon'" >> /home/$USERNAME/.bashrc
148205

@@ -219,6 +276,7 @@ RUN sudo apt-get -q update \
219276
&& sudo apt-get -q -y upgrade \
220277
&& vcs import src < src/blue/sim.repos \
221278
&& rosdep update \
279+
&& . "${MAVROS_WORKSPACE}/install/setup.sh" \
222280
&& rosdep install -y --from-paths src --ignore-src --rosdistro ${ROS_DISTRO} \
223281
&& sudo apt-get autoremove -y \
224282
&& sudo apt-get clean -y \
@@ -227,7 +285,7 @@ RUN sudo apt-get -q update \
227285
# For users that build this on a laptop or system with limited RAM,
228286
# Modify the 'colcon build' line to be 'MAKEFLAGS="-j1 -l1" colcon build'
229287
# This will limit the amount of RAM that colcon is allowed to use
230-
RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" \
288+
RUN . "${MAVROS_WORKSPACE}/install/setup.sh" \
231289
&& colcon build
232290

233291
# Setup the simulation environment variables

0 commit comments

Comments
 (0)