Я работаю над перемещением сборки для проекта С++ в образ докеры. Изображение будет построено и нажато заданием Дженкинса. До докеров я сильно использовал ccache, чтобы ускорить мои разработки на Jenkins, особенно в случае сборок, где очень мало изменилось. Проблема с докером заключается в том, что сборка теперь работает в изолированной среде, поэтому я больше не могу использовать ccache. Есть ли способ построить внутри эфемерного контейнера, все еще используя ccache?
Использование ccache при создании внутри докера
Ответ 1
Вы все еще можете использовать ccache вместе со своей сборкой.
Создайте том данных, чтобы данные сохранялись между компиляциями/сборками с помощью следующей команды:
$ docker create -v /mnt/ccache:/ccache --name ccache debian
Затем создайте свой контейнер, который "монтирует" созданный выше контейнер данных, используя --volumes-from
командной строки --volumes-from
.
$ docker run -e CCACHE_DIR=/ccache --volumes-from ccache -it debian
Теперь вы будете в оболочке контейнера debian и сможете установить необходимые приложения и протестировать ccache:
[email protected]:/# apt-get update && apt-get install -y gcc ccache
Теперь вы можете проверить кеш, и он будет пуст, как и ожидалось:
[email protected]:/# ccache -s
cache directory /ccache
cache hit (direct) 0
cache hit (preprocessed) 0
cache miss 0
files in cache 0
cache size 0 Kbytes
max cache size 1.0 Gbytes
Объем данных будет сохраняться, поэтому даже после завершения работы контейнера кэш все еще там. В будущих сборках, которые монтируют том (и задают переменную -e ENV), будет использоваться кэш.
Затем создайте простое приложение, запустите его и снова проверьте кэш:
[email protected]:/# cat > foo.c << __EOF__
int main(int argc, char **argv)
{
return 0;
}
__EOF__
[email protected]:/# PATH=/usr/lib/ccache:$PATH gcc -o foo.o -c foo.c
[email protected]:/# ccache -s
cache directory /ccache
cache hit (direct) 1
cache hit (preprocessed) 0
cache miss 1
files in cache 2
cache size 8 Kbytes
max cache size 1.0 Gbytes
Вы можете видеть, что кеш теперь заполнен, и дальнейшие сборки увидят улучшения производительности из-за этого.
Объем данных будет сохраняться, поэтому даже после завершения работы контейнера кэш все еще там. В будущих сборках, которые монтируют том (и задают переменную -e ENV
), будет использоваться кэш.
Этот пост в блоге хорошо объясняет это:
Ответ 2
ОК, как и обещал.
PreReqs
-
Быть на Докере 18.06 или выше
-
Запуск в экспериментальном режиме на клиенте и сервере (на момент написания)
Настройка экспериментального режима
Сервер: я создал следующий файл переопределения systemd:
cat /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --experimental -H fd://
Затем я выполнил systemctl daemon-reload; systemctl restart docker.service
systemctl daemon-reload; systemctl restart docker.service
На стороне клиента вам нужно установить и export DOCKER_BUILDKIT=1
переменную export DOCKER_BUILDKIT=1
Файл докера
Это основа файла Docker. Я создаю образ php, но вы можете создавать все, что захотите. Ключевые части комментария 1-й строки (необходимо указать докеру анализировать файл в экспериментальном режиме) и параметр --mount=type=cache,target=/ccache/
. Это тянет в папку кеша для этого этапа сборки. Убедитесь, что вы поместили его в каждую строку RUN, где вы запускаете компиляцию
# syntax = docker/dockerfile:experimental
FROM php:7.3-fpm-stretch
# Create app directory
WORKDIR /usr/src/app
# setup locales
RUN apt update && \
apt install -y locales && \
sed -i -e 's/# en_GB.UTF-8 UTF-8/en_GB.UTF-8 UTF-8/' /etc/locale.gen && \
locale-gen
ENV LANGUAGE=en_GB.UTF-8
ENV LANG=en_GB.UTF-8
ENV LC_ALL=en_GB.UTF-8
ENV CCACHE_DIR=/ccache
RUN apt update ; apt install -yq \
git \
cloud-guest-utils \
iproute2 \
libxml2-dev \
libxslt1-dev \
libmemcached-dev \
libgd-dev \
libzip-dev \
libmemcached-dev \
ccache \
awscli
# use ccache (make it appear in path earlier then /usr/bin/gcc etc)
RUN for p in gcc g++ cc c++; do ln -vs /usr/bin/ccache /usr/local/bin/$p; done
# prod format
RUN --mount=type=cache,target=/ccache/ docker-php-source extract && \
docker-php-ext-install \
intl \
bcmath \
calendar \
exif \
gd \
gettext \
mysqli \
opcache \
pcntl \
pdo_mysql \
shmop \
soap \
sockets \
sysvmsg \
sysvsem \
sysvshm \
xsl \
zip \
&& \
docker-php-source delete
RUN --mount=type=cache,target=/ccache/ ccache -s
Образец вывода
Я запускаю сборку с --progress plain
флагом --progress plain
как результат в эксперименте очень отличается
#25 [16/16] RUN --mount=type=cache,target=/ccache/ ccache -s
#25 digest: sha256:98c661a0404c71176a4bbf7d02123184524a784fabb2575d5210da088f16ee3a
#25 name: "[16/16] RUN --mount=type=cache,target=/ccache/ ccache -s"
#25 started: 2019-07-01 09:35:15.158199623 +0000 UTC
#25 0.468 cache directory /ccache
#25 0.468 primary config /ccache/ccache.conf
#25 0.468 secondary config (readonly) /etc/ccache.conf
#25 0.468 cache hit (direct) 2450
#25 0.468 cache hit (preprocessed) 152
#25 0.468 cache miss 590
#25 0.468 cache hit rate 81.52 %
#25 0.468 called for link 163
#25 0.468 called for preprocessing 1011
#25 0.468 compile failed 33
#25 0.468 preprocessor error 3
#25 0.468 bad compiler arguments 188
#25 0.468 autoconf compile/link 943 #25 0.468 no input file 554
#25 0.468 cleanups performed 0
#25 0.468 files in cache 1288 #25 0.468 cache size 20.6 MB
#25 0.468 max cache size 5.0 GB
#25 completed: 2019-07-01 09:35:15.732702254 +0000 UTC
#25 duration: 574.502631ms
Больше чтений здесь: https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md https://docs.docker.com/engine/reference/commandline/dockerd/#description