代码之家  ›  专栏  ›  技术社区  ›  eivindml

缩小docker图像的大小

  •  4
  • eivindml  · 技术社区  · 6 年前

    我正在尝试部署Craft CMS到 zeit/now 100MB . 我的容器当前 176MB .

    alpine , nginx php 由Craft所需的模块,并使用多阶段构建来构建Composer组件,以减少构建工件的大小。

    这是 Dockerfile :

    FROM zeit/wait-for:0.2 as wait
    
    # Build dependencies
    FROM composer:latest as vendor
    
    COPY composer.json composer.json
    COPY composer.lock composer.lock
    
    RUN composer install --ignore-platform-reqs --no-interaction --no-plugins --no-scripts --prefer-dist --no-dev
    
    FROM alpine:3.8
    
    LABEL maintainer="Eivind Mikael Lindbråten <eivindml@icloud.com>"
    LABEL description="Minimal Craft CMS Container using nginx."
    
    # install nginx, php, and php extensions for Craft
    RUN apk add --no-cache \
        bash \
        nginx \
        php7 \
        php7-fpm \
        php7-opcache \
        php7-phar \
        php7-zlib \
        php7-ctype \
        php7-session \
        php7-fileinfo \
    # Required php extensions for Craft
        php7-pdo \
        php7-pdo_mysql \
        php7-gd \
        php7-openssl \
        php7-mbstring \
        php7-json \
        php7-curl \
        php7-zip \
    # Optional extensions for Craft
        php7-iconv \
        php7-intl \
        php7-dom
    
    COPY nginx.conf /etc/nginx/nginx.conf
    COPY www.conf /etc/php7/php-fpm.d/
    
    # Copy over Craft files
    COPY config/ /www/config
    COPY modules/ /www/modules
    COPY storage/ /www/storage
    COPY templates/ /www/templates
    COPY storage/ /www/storage
    COPY web/ /www/web
    COPY .env /www/.env
    COPY composer.json /www/composer.json
    COPY composer.lock /www/composer.lock
    
    # Copy over vendor files
    COPY --from=vendor /app/vendor /www/vendor
    
    # Set permissions
    RUN chmod 777 -R /www/config
    RUN chmod 777 -R /www/vendor
    RUN chmod 777 -R /www/storage
    RUN chmod 777 -R /www/web/cpresources
    RUN chmod 777 /www/.env
    RUN chmod 777 /www/composer.json
    RUN chmod 777 /www/composer.lock
    
    # Expose default port
    EXPOSE 80
    
    SHELL ["/bin/bash", "-c"]
    COPY --from=wait /bin/wait-for /bin/wait-for
    
    CMD php-fpm7 -F & (wait-for /tmp/php7-fpm.sock && nginx) & wait -n
    

    2 回复  |  直到 6 年前
        1
  •  4
  •   KarlMW    6 年前

    编辑2018-09-26:很多编辑来整理我的错误,包括 全部的


    我从提供的存储库构建了一个映像,以便查看安装的包的完整列表,包括依赖项。我的构建没有完成,但是它已经足够产生一个图像了( 5ed25a4a3cf1 RUN apk add ... ,上面写着:

    OK: 150 MiB in 102 packages
    

    查看图片,我们看到根据 docker history (图像层 8138a6c99655 -您可能需要向右滚动才能看到“大小”列):

    user@host:~/docker-craft-nginx$ sudo docker history 5ed25a4a3cf1
    IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
    5ed25a4a3cf1        About a minute ago   /bin/sh -c #(nop) COPY dir:e9a848580d7409c11…   0B
    79bba3526427        About a minute ago   /bin/sh -c #(nop) COPY dir:41ddb696977d39ee6…   7.38kB
    f4d1e79f00b4        About a minute ago   /bin/sh -c #(nop) COPY dir:e9a848580d7409c11…   21B
    ab8ad35f5a93        About a minute ago   /bin/sh -c #(nop) COPY dir:4ff26c2555a73b795…   1.18kB
    29a6368b96c5        About a minute ago   /bin/sh -c #(nop) COPY dir:cb92d968d83d14948…   3.43kB
    ea429fb6f1fa        About a minute ago   /bin/sh -c #(nop) COPY file:b1cc7638b7536f51…   139B
    f0e1dbcec6c5        About a minute ago   /bin/sh -c #(nop) COPY file:e0f1165c2cf43ac3…   1.07kB
    8138a6c99655        About a minute ago   /bin/sh -c apk add --no-cache     bash     n…   145MB
    b743c478b647        2 minutes ago        /bin/sh -c #(nop)  LABEL description=Minimal…   0B
    f3dab9765884        2 minutes ago        /bin/sh -c #(nop)  LABEL maintainer=Eivind M…   0B
    196d12cf6ab1        11 days ago          /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
    <missing>           11 days ago          /bin/sh -c #(nop) ADD file:25c10b1d1b41d46a1…   4.41MB
    

    给定要安装的包的完整列表(它们在映像构建期间显示),我们可以使用 apk info -s NAME_OF_PACKAGE

    user@host:~$ sudo docker run -it alpine sh -c "apk update; apk info -s ncurses-terminfo-base ncurses-terminfo ncurses-libs readline bash libxau libbsd libxdmcp libxcb libx11 libxext libbz2 expat libpng freetype fontconfig libgcc libgomp lcms2 libltdl libxml2 imagemagick-libs libxrender pixman cairo libffi libintl libuuid libblkid libmount pcre glib dbus-libs avahi-libs gmp nettle p11-kit libtasn1 libunistring gnutls libstdc++ cups-libs jbig2dec libjpeg-turbo tiff ghostscript libxft graphite2 harfbuzz pango libcroco shared-mime-info gdk-pixbuf librsvg libwebp imagemagick nginx php7-common libedit php7 php7-ctype ca-certificates nghttp2-libs libssh2 libcurl php7-curl php7-dom php7-fileinfo php7-fpm libice libsm libxt libxpm php7-gd php7-iconv php7-imagick icu-libs php7-intl php7-json php7-mbstring php7-opcache php7-openssl php7-pdo php7-mysqlnd php7-pdo_mysql php7-phar php7-session libzip php7-zip" | awk '/^[0-9]/{gsub(/[^0-9]+$/,"",$1); print $1,prev,"\r"; next}{prev=$1}' | sort -gr | head -n 20
    50036736 ghostscript-9.24-r0
    31248384 icu-libs-60.2-r2
    7245824 ncurses-terminfo-6.1_p20180818-r1
    5070848 php7-fileinfo-7.2.10-r0
    4849664 php7-fpm-7.2.10-r0
    4775936 php7-7.2.10-r0
    4489216 imagemagick-7.0.7.32-r0
    3440640 imagemagick-libs-7.0.7.32-r0
    3379200 libx11-1.6.5-r1
    3010560 glib-2.56.1-r0
    2338816 shared-mime-info-1.9-r0
    2203648 harfbuzz-1.7.6-r1
    1638400 php7-mbstring-7.2.10-r0
    1470464 libunistring-0.9.7-r0
    1384448 libstdc++-6.4.0-r8
    1282048 gnutls-3.6.2-r0
    1236992 p11-kit-0.23.10-r0
    1224704 libxml2-2.9.8-r0
    1187840 libcroco-0.6.12-r1
    1175552 nginx-1.14.0-r1
    

    把所有的包裹放在一起:

    user@host:~$ sudo docker run -it alpine sh -c "apk update; apk info -s ncurses-terminfo-base ncurses-terminfo ncurses-libs readline bash libxau libbsd libxdmcp libxcb libx11 libxext libbz2 expat libpng freetype fontconfig libgcc libgomp lcms2 libltdl libxml2 imagemagick-libs libxrender pixman cairo libffi libintl libuuid libblkid libmount pcre glib dbus-libs avahi-libs gmp nettle p11-kit libtasn1 libunistring gnutls libstdc++ cups-libs jbig2dec libjpeg-turbo tiff ghostscript libxft graphite2 harfbuzz pango libcroco shared-mime-info gdk-pixbuf librsvg libwebp imagemagick nginx php7-common libedit php7 php7-ctype ca-certificates nghttp2-libs libssh2 libcurl php7-curl php7-dom php7-fileinfo php7-fpm libice libsm libxt libxpm php7-gd php7-iconv php7-imagick icu-libs php7-intl php7-json php7-mbstring php7-opcache php7-openssl php7-pdo php7-mysqlnd php7-pdo_mysql php7-phar php7-session libzip php7-zip" | awk '/^[0-9]+/ {s+=$1} END {printf "%.0f\n", s}'
    152952832
    


    编辑2018-09-25:在纠正了我之前的错误之后,这现在没有那么有用了,但是也许还有一些相关的信息:在我看来,即使我构建的完整图像失败了,我也不在乎为什么-我们只对安装apk的大层感兴趣。所以,我做了一个非常小的dockerfile:

    FROM alpine:3.8
    
    # install nginx, php, and php extensions for Craft
    RUN apk add --no-cache \
        bash \
        nginx \
        php7 \
        php7-fpm \
        php7-opcache \
        php7-phar \
        php7-zlib \
        php7-ctype \
        php7-session \
        php7-fileinfo \
    # Required php extensions for Craft
        php7-pdo \
        php7-pdo_mysql \
        php7-gd \
        php7-openssl \
        php7-mbstring \
        php7-json \
        php7-curl \
        php7-zip \
    # Optional extensions for Craft
        php7-iconv \
        php7-intl \
        php7-dom \
    # Extra Optional extensions for Craft
        imagemagick \
        php7-imagick
    
    CMD sh
    

    建造它: sudo docker build . Successfully built e344a23763c9 sudo docker run -it e344a23763c9 ncdu (我可以通过dockerfile安装)使用 apk add --no-cache ncdu 然后跑了 ncdu / -现在我可以很容易地看到大目录的位置,从根目录开始(注意:我已经从输出中修剪了小文件和目录):

      146.0 MiB [##########] /usr                                                                                                                                  
        3.6 MiB [          ] /lib
        2.0 MiB [          ] /etc
        1.4 MiB [          ] /bin
    

    导航到 /usr

       84.4 MiB [##########] /lib
       35.6 MiB [####      ] /share
       20.5 MiB [##        ] /bin
        5.5 MiB [          ] /sbin
    

    /usr/lib :

       25.7 MiB [##########]  libicudata.so.60.2
       15.0 MiB [#####     ]  libgs.so.9.24
        9.0 MiB [###       ] /php7
        3.9 MiB [#         ] /ImageMagick-7.0.7
        2.3 MiB [          ]  libicui18n.so.60.2
        2.2 MiB [          ]  libMagickCore-7.Q16HDRI.so.6.0.0
        1.5 MiB [          ]  libicuuc.so.60.2
        1.4 MiB [          ]  libgio-2.0.so.0.5600.1
        1.4 MiB [          ]  libunistring.so.2.0.0
        1.3 MiB [          ]  libstdc++.so.6.0.22
        1.2 MiB [          ]  libgnutls.so.30.20.2
        1.2 MiB [          ]  libxml2.so.2.9.8
        1.1 MiB [          ]  libX11.so.6.3.0
        1.1 MiB [          ]  libMagickWand-7.Q16HDRI.so.6.0.0
        1.1 MiB [          ]  libp11-kit.so.0.3.0
    

    /usr/share :

       17.7 MiB [##########] /ghostscript
        6.9 MiB [###       ] /terminfo
        5.6 MiB [###       ] /mime
        2.3 MiB [#         ] /gtk-doc
        2.1 MiB [#         ] /X11
    

    /usr/bin :

       14.8 MiB [##########]  gs
        4.5 MiB [###       ]  php7
    

    在我看来 imagemagick 是唯一最大的贡献者(以及它的依赖性 ghostscript ). 运行一个没有 php7-imagick 生成65.8MB的图像层大小(如 ).

    拆卸 php7-intl libicudata.so.60.2 它是“Unicode国际组件”的一部分)

    如果你想要一个比你原来的小的容器,我想你要么需要放弃图像处理和国际化,要么找到更小的方法来实现它们——它们远远是最大的可裁剪组件(取决于你想要实现什么)。


    通过将 chmod 电话:

    RUN chmod 777 -R \
       /www/config \
       /www/vendor \
       /www/storage \
       /www/web/cpresources \
    && chmod 777 \
       /www/.env \
       /www/composer.json \
       /www/composer.lock
    

    编辑2018-09-29:我注意到图像中的terminfo数据库[可能]过多-根据阿尔卑斯软件包数据库条目 ncurses-terminfo

    我找不到一个简单的方法来不安装这个包(其他事情需要安装它,我找不到一个合理的方法来强制安装) apk 运行apk add。。。 在提交层之前删除未使用的终端的行-删除其中的大部分 files

        2
  •  -1
  •   Mureinik    6 年前

    你可以做的一件事就是移除 apk 毕竟缓存 apk add 通话完毕:

    RUN rm -rf /var/cache/apk