Я пытаюсь развернуть Craft CMS в Zeit / в настоящее время используя Docker. Это работает локально, но Zeit имеет ограничение размера изображения 100MB
, Мой контейнер в настоящее время 176MB
,
Это изображение Docker, использующее 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 <[email protected]>"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
Глядя на изображение, мы видим, что пакеты составляют 145 МБ в соответствии с 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
(Я отсортировал их по порядку, уменьшив размер, и показываю только первые 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
На данный момент, похоже, что ваша проблема — проблема «у вас слишком большой материал», а не проблема докера. Вы могли или не могли знать эту часть раньше, но я узнал кое-что о копании в докере, так что это было весело 🙂
Изменить 2018-09-25: теперь это не так полезно после исправления моих предыдущих ошибок, но, возможно, все еще содержит некоторую соответствующую информацию: мне приходит в голову, что, хотя моя сборка полного изображения не удалась, мне все равно, почему — Мы заинтересованы только в том, чтобы ковыряться в большом слое, где установлены apks. Итак, я сделал довольно минимальный 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 /
— теперь я могу легко видеть, где находятся большие каталоги, начиная с корня (Примечание: я обрезал маленькие файлы & dirs с выхода):
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,8 МБ (как сообщает docker history
).
Удаление php7-intl
получает слой до 32,7 МБ (в основном, удаляя 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 в изображении [вероятно] чрезмерна — почти 7 МБ в соответствии с записью базы данных пакета Alpine для Ncurses-TERMINFO. У него есть terminfos практически для каждого возможного термина, что кажется избыточным для контейнера докера (в зависимости от того, что вы делаете).
Я не вижу простого способа не установить этот пакет (другие вещи требуют его установки, и я не смог найти разумный способ заставить его apk
не уважать зависимость), но вы могли бы получить RUN apk add ...
строка для удаления неиспользованных terminfos перед фиксацией слоя — удалить большинство из них файлы.
Одна вещь, которую вы, безусловно, можете сделать, это удалить apk
кеш в конце концов apk add
звонки сделаны:
RUN rm -rf /var/cache/apk