在docker内部构建时使用ccache

Vip*_*ley 12 ccache docker

我正在努力将C++项目的构建移动到docker镜像中.该图像将由Jenkins工作构建和推送.在docker之前,我大量使用ccache来加速我在Jenkins上的构建,特别是在构建几乎没有变化的情况下.docker的问题在于构建现在在隔离的环境中运行,因此我无法再从ccache中受益.有没有办法在仍然利用ccache的同时构建一个短暂的容器内部?

Dev*_*Dan 10

您仍然可以将ccache与您的构建结合使用.

使用以下命令创建数据卷以允许数据在编译/构建之间保持不变:

$ docker create -v /mnt/ccache:/ccache --name ccache debian
Run Code Online (Sandbox Code Playgroud)

然后使用--volumes-from命令行选项创建"安装"上面创建的数据容器的容器.

$ docker run -e CCACHE_DIR=/ccache --volumes-from ccache -it debian
Run Code Online (Sandbox Code Playgroud)

现在你将进入debian容器的shell,可以安装所需的应用程序并测试ccache:

root@15306d02505a:/# apt-get update && apt-get install -y gcc ccache    
Run Code Online (Sandbox Code Playgroud)

现在,此时您可以检查缓存,它将按预期为空:

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
Run Code Online (Sandbox Code Playgroud)

数据卷将保持不变,因此即使在容器终止后,缓存仍然存在.挂载卷的未来构建(并指定-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
Run Code Online (Sandbox Code Playgroud)

您可以看到现在已填充缓存,并且进一步构建将因此而看到性能改进.

数据卷将保持不变,因此即使在容器终止后,缓存仍然存在.挂载卷的未来构建(并指定-e ENV变量)将使用缓存.

这篇博文很好地解释了它:

在Docker中使用Ccache

  • 这不是问题的答案,它对于运行时来说是一个很好的答案,但对于构​​建时间来说却不是。如果我找到正确的答案,我会回复 (3认同)
  • 问题是(我可能只是误解)我想要根据我的构建创建一个图像.这种方法似乎让我在容器中使用ccache但不使用docker build命令. (2认同)

kra*_*rad 8

像承诺的那样好。

先决条件

  1. 使用 Docker 18.06 或更高版本

  2. 在客户端和服务器上以实验模式运行(在撰写本文时)

设置实验模式

服务器:我创建了以下 systemd 覆盖文件:

cat /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --experimental -H fd:// 
Run Code Online (Sandbox Code Playgroud)

然后我做了一个 systemctl daemon-reload ; systemctl restart docker.service

您需要设置和 env 变量的客户端 export DOCKER_BUILDKIT=1

Docker 文件

这是 docker 文件的基础。我正在构建一个 php 图像,但您可以构建任何您想要的。第一行注释的关键部分(需要告诉docker在实验模式下解析文件),以及--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
Run Code Online (Sandbox Code Playgroud)

样本输出

我正在运行带有--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
Run Code Online (Sandbox Code Playgroud)

更多阅读在这里:https : //github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md https://docs.docker.com/engine/reference/commandline/dockerd/#description