Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to reduce the size of a custom Docker image

I've built a custom Docker image based off an official PHP FPM image php:7.0.14-fpm-alpine

I wanted to keep the size of the image small, so I went for the official alpine PHP-FPM version as it weighs only 27 MB.

I installed only few additional packages through my Dockerfile, and the image grew in size to as much as 277.5 MB. Here is my Dockerfile:

FROM php:7.0.14-fpm-alpine

COPY ./config/www-pool.conf /usr/local/etc/php-fpm.d/www.conf
COPY ./scripts/download-composer.sh /root/download-composer.sh

WORKDIR /root

RUN chmod +x download-composer.sh \
    && ./download-composer.sh \
    && mv composer.phar /usr/local/bin/composer

RUN ["mkdir", "/var/log/php-fpm"]

RUN apk --update add \
      autoconf g++ make \
      openssl-dev \
      libxml2-dev

RUN pecl install \
        xdebug \
        mongodb

RUN docker-php-ext-enable \
        xdebug.so \
        mongodb.so

RUN  docker-php-ext-install \
        pdo_mysql \
        soap

RUN addgroup sudo
RUN adduser -S luqo33 -G sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers

277.5 MB is a ten-fold increase in size compared to the base image. Apart from Composer, all I needed were several PHP extensions:

  • mongodb
  • xdebug
  • pdo
  • soap

I'm not sure what contributed the most to increasing the size of my image so much. I suspect that it might be due to the dev dependencies that needed to be installed in order to successfully run pecl (openssl-dev, libxml2-dev), and that might have installed their own tree of dependencies.

Could you please advise on how I can reduce the size of my custom PHP-FPM image and still keep the necessary extensions?

like image 432
luqo33 Avatar asked Dec 26 '16 14:12

luqo33


1 Answers

I built the initial part of your image two different ways to test this. A common answer to this question is that the package index takes up extra space. In the case of Alpine Linux (using APK), you can clean up the package index like this:

rm -rf /var/cache/apk/*

However, I built the first part of the image both with and without that cleanup. It made hardly any difference (0.8 MB).

FROM php:7.0.14-fpm-alpine

WORKDIR /root

RUN ["mkdir", "/var/log/php-fpm"]

RUN apk --update add \
      autoconf g++ make \
      openssl-dev \
      libxml2-dev \
  && rm -rf /var/cache/apk/*

Whether the cleanup command is present or not, the image weighs in at 267MB.

REPOSITORY             TAG      IMAGE ID       CREATED          SIZE
php-fpm-alpine-test2   latest   b87f5e2d629d   23 seconds ago   267.1 MB
php-fpm-alpine-test1   latest   8ff7df8bebea   6 minutes ago    267.9 MB

The space used is simply the packages you're installing.

Step 4 : RUN apk --update add       autoconf g++ make       openssl-dev       libxml2-dev   && rm -rf /var/cache/apk/*
 ---> Running in 037a929d9e6a
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
(1/23) Installing m4 (1.4.17-r1)
(2/23) Installing perl (5.22.2-r0)
(3/23) Installing autoconf (2.69-r0)
(4/23) Installing libgcc (5.3.0-r0)
(5/23) Installing libstdc++ (5.3.0-r0)
(6/23) Installing binutils-libs (2.26-r0)
(7/23) Installing binutils (2.26-r0)
(8/23) Installing gmp (6.1.0-r0)
(9/23) Installing isl (0.14.1-r0)
(10/23) Installing libgomp (5.3.0-r0)
(11/23) Installing libatomic (5.3.0-r0)
(12/23) Installing pkgconf (0.9.12-r0)
(13/23) Installing pkgconfig (0.25-r1)
(14/23) Installing mpfr3 (3.1.2-r0)
(15/23) Installing mpc1 (1.0.3-r0)
(16/23) Installing gcc (5.3.0-r0)
(17/23) Installing musl-dev (1.1.14-r14)
(18/23) Installing libc-dev (0.7-r0)
(19/23) Installing g++ (5.3.0-r0)
(20/23) Installing zlib-dev (1.2.8-r2)
(21/23) Installing libxml2-dev (2.9.4-r0)
(22/23) Installing make (4.1-r1)
(23/23) Installing openssl-dev (1.0.2j-r0)
Executing busybox-1.24.2-r11.trigger
OK: 220 MiB in 48 packages

As you can see from the summary at the end of this installation, apk has installed 220 MiB of new content.

My best advice would be to run all of your installation and then you can try to remove some of the packages that are only needed for build, not at run-time. For instance you may not need some of the dev packages anymore, or the compiler, automake, etc.

However, you have to keep in mind that each RUN command makes a new layer. To actually save space this way, you would have to run your apk command, all of your other installs, and the post-install cleanup, in a single RUN command, to make a single layer of it. Otherwise, whether you clean up or not, the earlier layers will still have the content and will still contribute to the image size.

RUN apk --update add \
      autoconf g++ make \
      openssl-dev \
      libxml2-dev \
    && pecl install \
        xdebug \
        mongodb \
    && docker-php-ext-enable \
        xdebug.so \
        mongodb.so \
    && docker-php-ext-install \
        pdo_mysql \
        soap \
    && apk del autoconf g++ make openssl-dev libxml2-dev \
    && rm -rf /var/cache/apk/*
like image 168
Dan Lowe Avatar answered Oct 29 '22 06:10

Dan Lowe