Optimizing Docker Images

Docker images can sometimes be huge and present a limitation when using devices that have limited storage (such as small SD cards). In the following we provide some advanced guidelines that can help reducing the size of the Docker images that will be pushed to the Docker registries:

  • Perform the less RUN steps as possible. In fact each RUN creates one layer and therefore one file system.
  • Make sure to use --no-install-recommends when installing from apt-get package manager.
  • Clean /var/lib/apt/lists/ at the end of each RUN command that installs packages with apt-get.
  • Make sure to remove all the tarballs that were copied during the installation
RUN apt-get update -y && \
    apt-get autoremove -y && \
    apt-get install --no-install-recommends lsb-release && \
    tar -xvf archive.tar.gz &&\
    rm -rf /var/lib/apt/lists/* && \
    rm -rf *.tar.gz
RUN apt-get update
RUN apt-get autoremove -y
RUN apt-get install lsb-release
RUN tar -xvf archive.tar.gz 

Using Multi-stage Builds

In any case, we recommend doing multi-stages builds to optimize image size and deployments. With multistage builds, only the runtime binaries are copied in the docker image and pushed to the registry. In this case we recommend creating your image in two main steps:

For the first step:

  • Rename the FROM as builder (or any other name) and proceed with the installation of all the dependencies that will allow compiling the application with static links. This step does not need to be optimized since it will not be pushed to the registry.
FROM stereolabs/zed:2.8-devel-cuda10.0-ubuntu18.04 AS builder
COPY CMakeLists.txt .
COPY src src
COPY include include
RUN mkdir /path/to/application/build && cd /path/to/application/build && \
    cmake -DLINK_SHARED_ZED=OFF .. && make -j2

During the second step:

  • Perform a FROM that will looks for the minimal requirements to run the application. For an application running on Ubuntu 18.04, we can use:
FROM nvidia/10.0-base-ubuntu18.04
  • Install any dependency that will be required for runtime and has not been compiled with static link.
  • Finally just COPY the built artifact from the previous stage into this new stage.
COPY --from=builder /path/to/app .

Once the Dockerfile ready, build the image and push it to a Docker registry. The image will have the size of the second stage (the second FROM) and will be lighter than the original one.