在 docker 内部构建时使用 ccache
Using ccache when building inside of docker
我正在努力将 C++ 项目的构建移动到 docker 映像中。该图像将由 Jenkins 作业构建和推送。在 docker 之前,我大量使用 ccache 来加速我在 Jenkins 上的构建,尤其是在构建变化很小的情况下。 docker 的问题在于构建现在在隔离环境中运行,因此我无法再从 ccache 中受益。有没有办法在仍然利用 ccache 的同时构建临时容器内部?
您仍然可以将 ccache 与您的构建结合使用。
使用以下命令创建 Data Volume 以允许数据在 compilations/builds 之间保留:
$ docker create -v /mnt/ccache:/ccache --name ccache debian
然后使用 --volumes-from
命令行选项创建“装载”上面创建的数据容器的容器。
$ docker run -e CCACHE_DIR=/ccache --volumes-from ccache -it debian
现在您将进入 debian 容器的 shell,可以安装所需的应用程序并测试 ccache:
root@15306d02505a:/# apt-get update && apt-get install -y gcc ccache
此时您可以检查缓存,它会如预期的那样为空:
root@15306d02505a:/# 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 变量)的未来构建将利用缓存。
然后创建一个简单的应用程序,运行它,并再次检查缓存:
root@15306d02505a:/# cat > foo.c << __EOF__
int main(int argc, char **argv)
{
return 0;
}
__EOF__
root@15306d02505a:/# PATH=/usr/lib/ccache:$PATH gcc -o foo.o -c foo.c
root@15306d02505a:/# 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
变量)将利用缓存。
这个博客 post 很好地解释了它:
如约而至。
先决条件
在 Docker 18.06 或以上
运行 处于实验模式,在客户端和服务器上(在撰写本文时)
设置实验模式
服务器:
我创建了以下系统覆盖文件:
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
客户端需要设置环境变量
export DOCKER_BUILDKIT=1
Docker 文件
这是 docker 文件的基础。我正在构建一个 php 图像,但您可以构建任何您想要的图像。第一行注释的关键部分(需要告诉 docker 在实验模式下解析文件)和 --mount=type=cache,target=/ccache/
选项。这将拉入该构建阶段的缓存文件夹。确保将它放在触发编译
的每个 运行 行上
# 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
标志的构建,因为实验中的输出非常不同
#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
我正在努力将 C++ 项目的构建移动到 docker 映像中。该图像将由 Jenkins 作业构建和推送。在 docker 之前,我大量使用 ccache 来加速我在 Jenkins 上的构建,尤其是在构建变化很小的情况下。 docker 的问题在于构建现在在隔离环境中运行,因此我无法再从 ccache 中受益。有没有办法在仍然利用 ccache 的同时构建临时容器内部?
您仍然可以将 ccache 与您的构建结合使用。
使用以下命令创建 Data Volume 以允许数据在 compilations/builds 之间保留:
$ docker create -v /mnt/ccache:/ccache --name ccache debian
然后使用 --volumes-from
命令行选项创建“装载”上面创建的数据容器的容器。
$ docker run -e CCACHE_DIR=/ccache --volumes-from ccache -it debian
现在您将进入 debian 容器的 shell,可以安装所需的应用程序并测试 ccache:
root@15306d02505a:/# apt-get update && apt-get install -y gcc ccache
此时您可以检查缓存,它会如预期的那样为空:
root@15306d02505a:/# 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 变量)的未来构建将利用缓存。
然后创建一个简单的应用程序,运行它,并再次检查缓存:
root@15306d02505a:/# cat > foo.c << __EOF__
int main(int argc, char **argv)
{
return 0;
}
__EOF__
root@15306d02505a:/# PATH=/usr/lib/ccache:$PATH gcc -o foo.o -c foo.c
root@15306d02505a:/# 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
变量)将利用缓存。
这个博客 post 很好地解释了它:
如约而至。
先决条件
在 Docker 18.06 或以上
运行 处于实验模式,在客户端和服务器上(在撰写本文时)
设置实验模式
服务器: 我创建了以下系统覆盖文件:
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
客户端需要设置环境变量
export DOCKER_BUILDKIT=1
Docker 文件
这是 docker 文件的基础。我正在构建一个 php 图像,但您可以构建任何您想要的图像。第一行注释的关键部分(需要告诉 docker 在实验模式下解析文件)和 --mount=type=cache,target=/ccache/
选项。这将拉入该构建阶段的缓存文件夹。确保将它放在触发编译
# 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
标志的构建,因为实验中的输出非常不同
#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