在Docker云上的自动构建中使用ccache

时间:2017-08-16 14:04:48

标签: docker dockerfile docker-cloud ccache

我在Docker云上使用自动构建来编译C ++应用程序并在图像中提供它。 编译时间很长(范围2-3小时),github上的提交频繁(每天约10到30次)。

有没有办法以某种方式保留构建缓存(使用ccache)?

据我了解,docker缓存是无用的,因为由于源代码更改,将不会使用生成ccache的编译层。 或者我们可以调整以将一些数据带回第一层吗?

还有其他解决方案吗?把它推到某个地方?

这是Dockerfile:

# CACHE_TAG is provided by Docker cloud
# see https://docs.docker.com/docker-cloud/builds/advanced/
# using ARG in FROM requires min v17.05.0-ce
ARG  CACHE_TAG=latest

FROM  qgis/qgis3-build-deps:${CACHE_TAG}
MAINTAINER Denis Rouzaud <denis.rouzaud@gmail.com>

ENV CC=/usr/lib/ccache/clang
ENV CXX=/usr/lib/ccache/clang++
ENV QT_SELECT=5

COPY  . /usr/src/QGIS

WORKDIR /usr/src/QGIS/build

RUN cmake \
 -GNinja \
 -DCMAKE_INSTALL_PREFIX=/usr \
 -DBINDINGS_GLOBAL_INSTALL=ON \
 -DWITH_STAGED_PLUGINS=ON \
 -DWITH_GRASS=ON \
 -DSUPPRESS_QT_WARNINGS=ON \
 -DENABLE_TESTS=OFF \
 -DWITH_QSPATIALITE=ON \
 -DWITH_QWTPOLAR=OFF \
 -DWITH_APIDOC=OFF \
 -DWITH_ASTYLE=OFF \
 -DWITH_DESKTOP=ON \
 -DWITH_BINDINGS=ON \
 -DDISABLE_DEPRECATED=ON \
 .. \
 && ninja install \
 && rm -rf /usr/src/QGIS

WORKDIR /

1 个答案:

答案 0 :(得分:1)

您应该尝试从第三方服务保存和恢复缓存数据: - 像Amazon S3这样的在线对象存储 - 一个简单的FTP服务器 - 使用ssh创建scp

的Internet可用计算机
  

我假设您的缓存数据存储在'〜/ .ccache'目录

使用Docker多级构建

从一段时间以来,Docker支持Multi-stage builds,您可以尝试使用它来实现具有单个Dockerfile的解决方案:

  

警告:我没有测试过它

# STAGE 1 - YOUR ORIGINAL DOCKER FILE CUSTOMIZED
# CACHE_TAG is provided by Docker cloud
# see https://docs.docker.com/docker-cloud/builds/advanced/
# using ARG in FROM requires min v17.05.0-ce
ARG  CACHE_TAG=latest

FROM  qgis/qgis3-build-deps:${CACHE_TAG} as builder
MAINTAINER Denis Rouzaud <denis.rouzaud@gmail.com>

ENV CC=/usr/lib/ccache/clang
ENV CXX=/usr/lib/ccache/clang++
ENV QT_SELECT=5

COPY  . /usr/src/QGIS

WORKDIR /usr/src/QGIS/build

# restore cache
RUN curl -o ccache.tar.bz2 http://my-object-storage/ccache.tar.bz2
RUN tar -xjvf ccache.tar.bz2
COPY --from=downloader /.ccache ~/.ccache

RUN cmake \
 -GNinja \
 -DCMAKE_INSTALL_PREFIX=/usr \
 -DBINDINGS_GLOBAL_INSTALL=ON \
 -DWITH_STAGED_PLUGINS=ON \
 -DWITH_GRASS=ON \
 -DSUPPRESS_QT_WARNINGS=ON \
 -DENABLE_TESTS=OFF \
 -DWITH_QSPATIALITE=ON \
 -DWITH_QWTPOLAR=OFF \
 -DWITH_APIDOC=OFF \
 -DWITH_ASTYLE=OFF \
 -DWITH_DESKTOP=ON \
 -DWITH_BINDINGS=ON \
 -DDISABLE_DEPRECATED=ON \
 .. \
 && ninja install

# save the current cache online
WORKDIR ~/
RUN tar -cvjSf ccache.tar.bz2 .ccache
RUN curl -T ccache.tar.bz2 -X PUT http://my-object-storage/ccache.tar.bz2


# STAGE 2
FROM alpine:latest
# YOUR CUSTOM LOGIC TO CREATE THE FINAL IMAGE WITH ONLY REQUIRED BINARIES
# USE THE FROM IMAGE YOU NEED, this is only an example
# E.g.:
# COPY --from=builder /usr/src/QGIS/build/YOUR_EXECUTABLE /usr/bin
# ...

在第2阶段,您将构建将推送到存储库的最终图像。

使用Docker云挂钩

另一种但不太清晰的方法可能是使用Docker Cloud pre_build挂钩文件来下载缓存数据:

#!/bin/bash
echo "=> Downloading build cache data"
curl -o ccache.tar.bz2 http://my-object-storage/ccache.tar.bz2 # e.g. Amazon S3 like service
cd /
tar -xjvf ccache.tar.bz2
  

显然,你可以使用专用的docker镜像来运行curl或tar将本地目录作为一个卷安装在这个脚本中。

然后,在构建期间使用.ccache命令在COPY调用之前复制cmake解压缩的容器内容:

WORKDIR /usr/src/QGIS/build

COPY /.ccache ~/.ccache    

RUN cmake ...

为了实现这一点,您应该找到一种在构建后上传缓存数据的方法,并且可以使用post_build挂钩文件轻松实现:

#!/bin/bash
echo "=> Uploading build cache data"
tar -cvjSf ccache.tar.bz2 ~/.ccache
curl -T ccache.tar.bz2 -X PUT http://my-object-storage/ccache.tar.bz2

但是你的编译数据不能从外部获得,因为它们存在于容器内。因此,您应该在主cmake内的Dockerfile命令之后上传缓存:

RUN cmake...
  && tar ...
  && curl ...
  && ninja ...
  && rm ...

如果curl或tar不可用,只需使用包管理器将它们添加到容器中(qgis/qgis3-build-deps基于Ubuntu 16.04,因此它们应该可用)。