11ARG 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
438ENV 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
687WORKDIR /root/ws_blue
788COPY . 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
1095RUN 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)
32120RUN 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#
49139FROM 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
66142USER $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-
130186WORKDIR $USER_WORKSPACE
131187RUN 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
144202RUN 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\n alias 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