php - 减小 docker 镜像的大小

标签 php docker nginx alpine craftcms

我正在尝试将 Craft CMS 部署到 zeit/now使用 Docker。它在本地工作,但 zeit 的图像大小限制为 100MB .我的容器当前是 176MB .

这是一个使用 alpine 的 Docker 镜像, nginxphp 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

有什么想法可以进一步减小这个尺寸吗?

最佳答案

编辑 2018-09-26:进行了大量编辑以整理我的错误并包含所有依赖项。我之前的大部分内容都无关紧要,现在我已经包含了所有依赖项并且有了可以合理加起​​来的数字。

我从提供的存储库构建了一个镜像,以便查看已安装包的完整列表,包括依赖项。我的构建没有完成,但它已经足够生成一个图像( 5ed25a4a3cf1 )来显示空间的位置。构建的一部分,在 RUN apk add ... 的末尾,它是这样说的:

OK: 150 MiB in 102 packages

查看图像,我们看到根据 docker history,这些包是 145MB。 (图像层 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 获取它们各自的大小。

(我已经按照尺寸减小的顺序对它们进行了排序,并且只显示了前 20 个)
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

在这一点上,看起来您的问题是“您的东西太大”的问题,而不是 docker 问题。你以前可能知道也可能不知道那部分,但我已经学到了一些关于在 docker 中挖掘的东西,所以这很有趣 :-)

编辑 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

build 它: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)。在没有 imagemagick 的情况下运行试用版& php7-imagick产生 65.8MB 的图像层大小(由 docker history 报告)。

删除 php7-intl将层减小到 32.7MB(主要是通过删除 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 的 alpine 包数据库条目,几乎 7MB .它几乎每个可能的术语都有 terminfos,这对于 docker 容器来说似乎有点矫枉过正(取决于你在做什么)。

我看不到不安装该软件包的简单方法(其他事情需要安装它,我找不到一种明智的方法来强制 apk 不遵守依赖项),但是您可以获得 RUN apk add ...在提交层之前删除未使用的 terminfos 的行 - 删除其中大部分 files .

关于php - 减小 docker 镜像的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52451808/

相关文章:

php - 访客计数器的MYSQL数据库表结构

javascript - 如何使用 AJAX 发送单独的表单数据以进行回复?

docker - 修改和重建Docker镜像

node.js - 子目录中带有 NGINX 的多 Node 应用程序

angularjs - 如何使用反向代理处理 Express 应用程序中的重定向

php - MYSQL - 连接 1 个表或另一个表,具体取决于是否存在匹配项

php - 我无法将 IP 添加到我的数据库中。为什么?

docker - 在Docker 1.10中无法解析主机名

php - DOCKER:运行gulp-php网站时出错

php - Magento Magmi 的 hhvm nginx toString 服务器错误