构建Docker镜像阶段能否挂载卷作为Chromium构建缓存?
问题解答:Docker Build阶段无法挂载外部卷存储构建缓存
很遗憾,你没法在docker build阶段挂载外部卷来存储构建缓存。Docker的构建过程是在一系列隔离的临时容器中执行的,VOLUME指令只是在镜像中声明一个“未来容器运行时会用到的挂载点”,在docker build过程中,这个挂载点并不会关联到你本地的目录——build阶段的所有文件操作都只会存在于镜像的层里,没法持久化到外部宿主机的卷中。
针对你的Chromium构建缓存需求,我给你调整一下方案,把缓存相关的操作移到容器运行时来做,这样就能通过挂载卷复用缓存了:
第一步:修改你的Dockerfile
主要调整点是把gclient sync从RUN指令(build阶段执行)移到容器启动时执行,同时明确缓存目录的挂载声明:
FROM ubuntu:16.04 # 调整环境变量,添加缓存目录 ENV SRC="/mychromiumfork/src" ENV OUT="/mychromiumfork/out" ENV CACHE="/mychromiumfork/cache" ENV GOOGLE_PLAY_AGREE_LICENSE="1" ENV LC_CTYPE="en_US.UTF-8" ENV CHROME_DEVEL_SANDBOX="1" # 添加源并安装基础依赖 RUN echo "deb http://archive.ubuntu.com/ubuntu trusty multiverse" >> /etc/apt/sources.list \ && apt-get update && apt-get install -qy \ git \ build-essential \ clang \ curl \ lsb-core \ sudo \ --no-install-recommends # 创建目录结构 RUN mkdir -p ${SRC} ${CACHE} # 复制gclient配置文件 COPY .gclient /mychromiumfork RUN touch /mychromiumfork/.gclient_entries # 复制源码 COPY src ${SRC} # 处理字体许可证 RUN echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections # 安装Android构建依赖 RUN chmod +x ${SRC}/build/*.sh \ && ${SRC}/build/install-build-deps-android.sh --no-prompt \ && apt-get clean \ && apt-get autoremove -y # 安装depot_tools ENV DEPOT_TOOLS /home/developer/depot_tools RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $DEPOT_TOOLS ENV PATH $PATH:$DEPOT_TOOLS RUN echo -e "\n# Add Chromium's depot_tools to the PATH." >> .bashrc RUN echo "export PATH=\"\$PATH:$DEPOT_TOOLS\"" >> .bashrc # 声明运行时挂载点(build阶段不生效,仅用于容器运行时) VOLUME ${OUT} VOLUME ${CACHE} # 设置工作目录 WORKDIR /mychromiumfork # 创建启动脚本,在容器运行时执行gclient sync(利用缓存) RUN echo '#!/bin/bash' > start_build.sh \ && echo "gclient sync --cache-dir ${CACHE}" >> start_build.sh \ && echo "cd ${SRC}" >> start_build.sh \ && echo "gn gen --args='target_os=\"android\" is_debug=true proprietary_codecs=true ffmpeg_branding=\"Chrome\"' ${OUT}/Debug" >> start_build.sh \ && echo "ninja -C ${OUT}/Debug chrome_public_apk" >> start_build.sh \ && chmod +x start_build.sh # 容器启动时执行脚本 CMD ["./start_build.sh"]
第二步:调整构建与运行命令
现在docker build只负责构建基础镜像,缓存的复用放在docker run阶段:
# 1. 构建镜像(不需要挂载卷) docker build -t mychromiumfork_builder . # 2. 运行容器时挂载本地缓存和输出目录 docker run -it \ -v ${PWD}/cache:/mychromiumfork/cache \ -v ${PWD}/out:/mychromiumfork/out \ mychromiumfork_builder
为什么这样可行?
docker build阶段生成的是包含所有依赖的基础镜像,不会执行gclient sync,所以每次build不会重复下载依赖;- 当你运行容器时,挂载的
cache卷会被gclient sync使用,第一次运行会下载缓存到本地目录,后续再运行容器时,gclient sync会直接复用本地缓存,大幅节省时间; out卷也能持久化构建输出,不用每次重新构建。
内容的提问来源于stack exchange,提问作者4ntoine
相关产品推荐
相关产品推荐

