由于已经有好几年了,该站点使用Jekyll静态站点生成器。 生成整个站点大约需要15分钟。 不久前,我决定设置Gulp以最小化HTML,以加快读者的页面浏览速度。 这项更改使构建时间增加了大约10分钟,总共约25分钟,这是很长的时间...太长了。 我想减少构建时间,所以我决定尝试一下。

初始状态

Docker映像用于构建站点。 该图像基于JRuby图像 :Ruby是Jekyll的基本技术堆栈,而Java是AsciiDoctor的PlantUML插件所必需的。

在该图像中,设置了以下堆栈:

  • 邦德勒
  • Node.js
  • 古尔普
FROM jruby:9

RUN  gem install  bundler \  (1)
    && curl -sL https://deb.nodesource.com/setup_9.x | bash - \  (2)
    && apt-get install -y nodejs graphviz \                      (3)
    && npm install -g gulp-cli                                   (4)


  1. 安装捆绑器
  2. 将Node.js存储库添加到APT
  3. 安装Node.js和Graphviz(这是PlantUML依赖项)
  4. 安装Gulp命令行界面

该图像被上传到私有Docker注册表中,供站点生成使用。



GitLab构建文件将安装必需的Gems和NPM软件包。 看起来如下:



image:registry.gitlab.com/nfrankel/nfrankel.gitlab.io:latest

before_script:
  -bundle install (1)
  -npm set progress=false && npm install (2)

pages:
  stage:deploy
  script:gulp
  only:
    -master



  1. 从Gemfile安装宝石

package.json

  1. 安装NPM软件包

问题在于,每次构建站点时,都需要安装Gems和NPM软件包。 这是一个问题,因为即使该站点至少每周构建一次,依存关系也相当稳定。 但是,安装成本将在每次构建期间支付。



分层所有的东西!



将以上依赖项从构建文件移至Docker层似乎是一个好主意。



第一步是将先前的图像移动到另一个位置, 例如, registry.gitlab.com/nfrankel/nfrankel.gitlab.io/base:latest registry.gitlab.com/nfrankel/nfrankel.gitlab.io/base:latest



第二步,在项目文件夹中创建第二个Dockerfile:



FROM registry.gitlab.com/nfrankel/nfrankel.gitlab.io/base:latest

ADD Gemfile /builds/nfrankel/nfrankel.gitlab.io/Gemfile                      (1)
ADD Gemfile.lock /builds/nfrankel/nfrankel.gitlab.io/Gemfile.lock            (1)
ADD package.json /builds/nfrankel/nfrankel.gitlab.io/package.json            (1)
ADD package-lock.json /builds/nfrankel/nfrankel.gitlab.io/package-lock.json  (1)
RUN cd /builds/nfrankel/nfrankel.gitlab.io \
&& bundle install\  (2)
    && npm set progress=false \
    && npm install                                                           (3)



  1. 将必要的文件添加到上下文
  2. 安装宝石
  3. 安装NPM软件包

经验丰富的Docker用户可能会意识到,在构建映像时,所有文件夹的内容都会发送到守护程序。 但是,仅需要上述4个文件。



为防止这种情况,第三步是创建一个.dockerignore文件,以仅发送那些文件:



** (1)
!Dockerfile         (2)
!Gemfile            (3)
!Gemfile.lock       (3)
!package.json       (3)
!package-lock.json  (3)



  1. 忽略每个文件

Dockerfile

  1. 本身
  2. 添加所需文件

现在可以构建依赖项的映像:



docker build-t registry.gitlab.com/nfrankel/nfrankel.gitlab.io/withdeps:latest .



最后,让我们更新GitLab构建文件:



image:registry.gitlab.com/nfrankel/nfrankel.gitlab.io/withdeps:latest (1)

                                                                        (2)
pages:
  stage:deploy
  script:gulp
  only:
    -master



  1. 使用依赖项引用Docker映像
  2. 删除依赖项获取步骤



结论



首先是第一件事:新的构建并没有提供任何明显的速度改进...主要是因为大部分构建时间都花在了最小化HTML上,而不是获取依赖项。 从好的方面来说,构建日志文件要短得多,并且更易于分析。



当然,此过程不仅是特定于Jekyll的,它也可以通过Maven构建来完成。




翻译自: https://blog.frankel.ch/layering-docker-images-dependencies/