编辑于2018年9月26日:进行了大量编辑来整理我的错误并包含所有依赖项。现在,我已经包含了所有依赖项,并且有合理的数字,因此我以前的探索大部分都是无关紧要的。
我从提供的存储库中构建了一个镜像,以查看安装的完整软件包列表,包括依赖项。我的构建未完成,但已经完成足够的工作来生成一个图像(5ed25a4a3cf1
),显示了空间的位置。在构建过程中,在RUN apk add ...
的末尾,它说:
OK: 150 MiB in 102 packages
从图片中可以看出,根据 docker history
命令查询的结果(镜像层 8138a6c99655
- 你可能需要向右滚动来查看大小列),这些软件包的大小为145MB:
user@host:~/docker-craft-nginx$ sudo docker history 5ed25a4a3cf1
IMAGE CREATED CREATED BY SIZE COMMENT
5ed25a4a3cf1 About a minute ago /bin/sh -c
79bba3526427 About a minute ago /bin/sh -c
f4d1e79f00b4 About a minute ago /bin/sh -c
ab8ad35f5a93 About a minute ago /bin/sh -c
29a6368b96c5 About a minute ago /bin/sh -c
ea429fb6f1fa About a minute ago /bin/sh -c
f0e1dbcec6c5 About a minute ago /bin/sh -c
8138a6c99655 About a minute ago /bin/sh -c apk add --no-cache bash n… 145MB
b743c478b647 2 minutes ago /bin/sh -c
f3dab9765884 2 minutes ago /bin/sh -c
196d12cf6ab1 11 days ago /bin/sh -c
<missing> 11 days ago /bin/sh -c
在安装镜像时,会显示要安装的所有软件包清单。可以使用 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编辑:在纠正了之前的错误后,这个信息现在可能已经没什么用了,但或许仍然有一些相关的信息:我意识到尽管我完整镜像的构建失败了,但我并不关心为什么 - 我们只对安装apks的大层进行调查。 所以,我制作了一个相当精简的dockerfile:
FROM alpine:3.8
RUN apk add --no-cache \
bash \
nginx \
php7 \
php7-fpm \
php7-opcache \
php7-phar \
php7-zlib \
php7-ctype \
php7-session \
php7-fileinfo \
php7-pdo \
php7-pdo_mysql \
php7-gd \
php7-openssl \
php7-mbstring \
php7-json \
php7-curl \
php7-zip \
php7-iconv \
php7-intl \
php7-dom \
imagemagick \
php7-imagick
CMD sh
命令行操作: sudo docker build .
,得到一个镜像 Successfully built e344a23763c9
。使用该镜像启动容器并进入shell sudo docker run -it e344a23763c9
。安装ncdu
工具(也可以通过dockerfile安装):apk add --no-cache ncdu
,然后运行ncdu /
,现在可以轻松查看文件夹占用空间,从根目录开始(注意:输出已省略小文件和目录)。
146.0 MiB [
3.6 MiB [ ] /lib
2.0 MiB [ ] /etc
1.4 MiB [ ] /bin
导航到
/usr
,我们发现:
84.4 MiB [
35.6 MiB [
20.5 MiB [
5.5 MiB [ ] /sbin
在
/usr/lib
目录下:
25.7 MiB [
15.0 MiB [
9.0 MiB [
3.9 MiB [
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 [
6.9 MiB [
5.6 MiB [
2.3 MiB [
2.1 MiB [
在
/usr/bin
目录下:
14.8 MiB [
4.5 MiB [
我认为,除了其依赖项
ghostscript
外,
imagemagick
是最大的贡献者。如果没有
imagemagick
和
php7-imagick
,则运行试验性构建将产生65.8MB的图像层大小(由
docker history
报告)。
删除
php7-intl
可将图层大小降至32.7MB(主要是通过删除“Unicode国际组件”中的
libicudata.so.60.2
实现的)。
如果您想要比原来更小的容器,则需要放弃图像处理和国际化,或者找到更小的方法来实现它们-它们是最大的可裁剪组件(取决于您想要实现什么)。
通过合并
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年9月29日:我注意到镜像中的terminfo数据库[可能]过于庞大 - 根据ncurses-terminfo的Alpine软件包数据库条目,它几乎占用了7MB。 它具有几乎每个可能术语的terminfos,这似乎对于Docker容器来说有些过度 (取决于您要做什么)。
我无法找到不安装该软件包的简单方法(其他东西需要它被安装,并且我找不到一个明智的方法来强制apk
不遵循依赖关系),但是您可以使RUN apk add ...
行在提交层之前删除未使用的terminfos - 删除这些文件中的大部分即可。