Skip to content

Commit

Permalink
Optimize Dockerfiles (#110)
Browse files Browse the repository at this point in the history
I was looking at the source Dockerfile for the
`ghcr.io/foxglove/rolling-ros2-bridge` image, and noticed some
optimizations that could be made. See commit history for details.

The only major change is swapping the base image for the ros2 bridge
from `ros-core` over to `ros-base`:

```
REPOSITORY                TAG                SIZE
foxglove_bridge_rolling   base (after)       1.03GB
foxglove_bridge_rolling   core (before)      945MB
ros                       rolling-ros-base   752MB
ros                       rolling-ros-core   474MB
ubuntu                    jammy              77.8MB
```
I did this as most of the large dependencies being manually installed
should already be provided by the base tag. While the resulting image is
a little larger `(1.03GB-945MB)=85MB`, the resulting size of the added
layers to be regularly pushed over the network and saved to disk with
every update to the bridge image is reduced from `(945MB-474MB)=471MB`
to just `(1.03GB-752MB)=278MB`. Given 1) most robots using docker are
more likely to have at least the image layers for the `ros-base` tag
cached locally already for other running ROS containers, 2) the lower
cadence of changed layers in the `ros-base` image, this should help
reduce the bandwidth and storage requirements for deploying these bridge
images.
  • Loading branch information
ruffsl committed Dec 12, 2022
1 parent 80e6a97 commit 8ab2fc6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 40 deletions.
33 changes: 18 additions & 15 deletions Dockerfile.ros1
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
ARG ROS_DISTRIBUTION=noetic
FROM ros:$ROS_DISTRIBUTION-ros-base
ARG ROS_DISTRIBUTION=noetic

# Set environment and working directory
ENV ROS_WS /ros1_ws
WORKDIR $ROS_WS

# Add package.xml so we can install package dependencies.
COPY package.xml /ros1_ws/src/ros-foxglove-bridge/package.xml
COPY package.xml src/ros-foxglove-bridge/

# Install rosdep dependencies
RUN . /opt/ros/$ROS_DISTRIBUTION/setup.sh && \
RUN . /opt/ros/$ROS_DISTRO/setup.sh && \
apt-get update && rosdep update && rosdep install -y \
--from-paths \
/ros1_ws/src \
src \
--ignore-src \
&& rm -rf /var/lib/apt/lists/*

# Add common files and ROS 1 source code
COPY CMakeLists.txt /ros1_ws/src/ros-foxglove-bridge/CMakeLists.txt
COPY foxglove_bridge_base /ros1_ws/src/ros-foxglove-bridge/foxglove_bridge_base
COPY nodelets.xml /ros1_ws/src/ros-foxglove-bridge/nodelets.xml
COPY ros1_foxglove_bridge /ros1_ws/src/ros-foxglove-bridge/ros1_foxglove_bridge
COPY CMakeLists.txt src/ros-foxglove-bridge/CMakeLists.txt
COPY foxglove_bridge_base src/ros-foxglove-bridge/foxglove_bridge_base
COPY nodelets.xml src/ros-foxglove-bridge/nodelets.xml
COPY ros1_foxglove_bridge src/ros-foxglove-bridge/ros1_foxglove_bridge

# Build the Catkin workspace and ensure it's sourced when a container is run
RUN . /opt/ros/$ROS_DISTRIBUTION/setup.sh \
&& cd /ros1_ws \
# Build the Catkin workspace
RUN . /opt/ros/$ROS_DISTRO/setup.sh \
&& catkin_make
RUN echo "source /ros1_ws/devel/setup.bash" >> ~/.bashrc

# Set the working folder at startup
WORKDIR /ros1_ws
# source workspace from entrypoint
RUN sed --in-place \
's|^source .*|source "$ROS_WS/devel/setup.bash"|' \
/ros_entrypoint.sh

# Run foxglove_bridge
CMD ["/bin/bash", "-c", "source /ros1_ws/devel/setup.bash && rosrun foxglove_bridge foxglove_bridge"]
CMD ["rosrun", "foxglove_bridge", "foxglove_bridge"]
44 changes: 19 additions & 25 deletions Dockerfile.ros2
Original file line number Diff line number Diff line change
@@ -1,48 +1,42 @@
ARG ROS_DISTRIBUTION=humble
FROM ros:$ROS_DISTRIBUTION-ros-core
ARG ROS_DISTRIBUTION=humble
FROM ros:$ROS_DISTRIBUTION-ros-base

# Set environment and working directory
ENV ROS_WS /ros2_ws
WORKDIR $ROS_WS

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
python3-colcon-common-extensions \
python3-rosdep \
nlohmann-json3-dev \
libasio-dev \
libssl-dev \
libwebsocketpp-dev \
&& rm -rf /var/lib/apt/lists/*

# Initialize rosdep
RUN rosdep init && rosdep update

# Add package.xml so we can install package dependencies.
COPY package.xml /ros2_ws/src/ros-foxglove-bridge/package.xml
COPY package.xml src/ros-foxglove-bridge/

# Install rosdep dependencies
RUN . /opt/ros/$ROS_DISTRIBUTION/setup.sh && \
apt-get update && rosdep install -y \
RUN . /opt/ros/$ROS_DISTRO/setup.sh && \
apt-get update && rosdep update && rosdep install -y \
--from-paths \
/ros2_ws/src \
src \
--ignore-src \
&& rm -rf /var/lib/apt/lists/*

# Add common files and ROS 2 source code
COPY CMakeLists.txt /ros2_ws/src/ros-foxglove-bridge/CMakeLists.txt
COPY foxglove_bridge_base /ros2_ws/src/ros-foxglove-bridge/foxglove_bridge_base
COPY ros2_foxglove_bridge /ros2_ws/src/ros-foxglove-bridge/ros2_foxglove_bridge

# Use the bash shell so we can use the source command
SHELL [ "/bin/bash" , "-c" ]
COPY CMakeLists.txt src/ros-foxglove-bridge/CMakeLists.txt
COPY foxglove_bridge_base src/ros-foxglove-bridge/foxglove_bridge_base
COPY ros2_foxglove_bridge src/ros-foxglove-bridge/ros2_foxglove_bridge

# Build the ROS 2 workspace and ensure it's sourced when a container is run
RUN source /opt/ros/$ROS_DISTRIBUTION/setup.bash \
&& cd /ros2_ws \
# Build the ROS 2 workspace
RUN . /opt/ros/$ROS_DISTRO/setup.sh \
&& colcon build --event-handlers console_direct+
RUN echo "source /ros2_ws/install/setup.bash" >> ~/.bashrc

# Set the working folder at startup
WORKDIR /ros2_ws
# source workspace from entrypoint
RUN sed --in-place \
's|^source .*|source "$ROS_WS/install/setup.bash"|' \
/ros_entrypoint.sh

# Run foxglove_bridge
CMD ["/bin/bash", "-c", "source /ros2_ws/install/setup.bash && ros2 run foxglove_bridge foxglove_bridge"]
CMD ["ros2", "run", "foxglove_bridge", "foxglove_bridge"]

0 comments on commit 8ab2fc6

Please sign in to comment.