我正在研究一个CloudBuild脚本,该脚本将构建一个多阶段Docker映像以进行集成测试。为了优化构建脚本,我选择使用Kaniko。 Dockerfile和cloudbuild.yaml文件的相关部分在下面提供。
cloudbuild.yaml
steps:
# Build BASE image
- name: gcr.io/kaniko-project/executor:v0.17.1
id: buildinstaller
args:
- --destination=gcr.io/$PROJECT_ID/<MY_REPO>-installer:$BRANCH_NAME
- --destination=gcr.io/$PROJECT_ID/<MY_REPO>-installer:$SHORT_SHA
- --cache=true
- --cache-ttl=24h
- --cache-repo=gcr.io/$PROJECT_ID/<MY_REPO>/cache
- --target=installer
# Build TEST image
- name: gcr.io/kaniko-project/executor:v0.17.1
id: buildtest
args:
- --destination=gcr.io/$PROJECT_ID/<MY_REPO>-test:$BRANCH_NAME
- --destination=gcr.io/$PROJECT_ID/<MY_REPO>-test:$SHORT_SHA
- --cache=true
- --cache-ttl=24h
- --cache-repo=gcr.io/$PROJECT_ID/<MY_REPO>/cache
- --target=test-image
waitFor:
- buildinstaller
# --- REMOVED SOME CODE FOR BREVITY ---
# Build PRODUCTION image
- name: gcr.io/kaniko-project/executor:v0.17.1
id: build
args:
- --destination=gcr.io/$PROJECT_ID/<MY_REPO>:$BRANCH_NAME
- --destination=gcr.io/$PROJECT_ID/<MY_REPO>:$SHORT_SHA
- --destination=gcr.io/$PROJECT_ID/<MY_REPO>:latest
- --cache=true
- --cache-ttl=24h
- --cache-dir=/cache
- --target=production-image
waitFor:
- test # TODO: This will run after tests which were not included here for brevity
images:
- gcr.io/$PROJECT_ID/<MY_REPO>
Dockerfile
FROM ruby:2.5-alpine AS installer
# Expose port
EXPOSE 3000
# Set desired port
ENV PORT 3000
# set the app directory var
ENV APP_HOME /app
RUN mkdir -p ${APP_HOME}
WORKDIR ${APP_HOME}
# Install necessary packanges
RUN apk add --update --no-cache \
build-base curl less libressl-dev zlib-dev git \
mariadb-dev tzdata imagemagick libxslt-dev \
bash nodejs
# Copy gemfiles to be able to bundle install
COPY Gemfile* ./
#############################
# STAGE 1.5: Test build #
#############################
FROM installer AS test-image
# Set environment
ENV RAILS_ENV test
# Install gems to /bundle
RUN bundle install --deployment --jobs $(nproc) --without development local_gems
# Add app files
ADD . .
RUN bundle install --with local_gems
#############################
# STAGE 2: Production build #
#############################
FROM installer AS production-image
# Set environment
ENV RAILS_ENV production
# Install gems to /bundle
RUN bundle install --deployment --jobs $(nproc) --without development test local_gems
# Add app files
ADD . .
RUN bundle install --with local_gems
# Precompile assets
RUN DB_ADAPTER=nulldb bundle exec rake assets:precompile assets:clean
# Puma start command
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
由于我的Docker映像是一个多阶段构建,具有2个单独的最终阶段,它们共享一个共同的基本构建,因此我想在共同部分和其他两个部分之间共享缓存。为此,我将所有构建都设置为共享同一缓存存储库- --cache-repo=gcr.io/$PROJECT_ID/<MY_REPO>/cache
。到目前为止,它在我的所有测试中都有效。但是,我无法确定这是否是最佳做法,或者是否建议使用其他缓存基本映像的方式。这是可以接受的实现吗?
我遇到过Kaniko-warmer,但无法根据情况使用它。
答案 0 :(得分:3)
在提及有关如何缓存基本映像的最佳做法之前,有一些最佳做法是为了optimize the performance of your build。由于您已经使用了Kaniko,并且正在从存储库中缓存映像,因此我相信您的实现遵循上述最佳实践。
我唯一的建议是使用Google Cloud Storage重用您以前构建的结果。如果您的构建需要很长时间,并且生成的文件不是很多,并且不需要花费很多时间将它们从 和复制到 Cloud Storage,可以加快构建速度。
此外,下一篇文章中还介绍了有关Optimization of your build cache的一些最佳做法。我相信其中最重要的是:
”将经常更改的构建步骤放在Dockerfile的底部。如果将它们放在顶部,则Docker无法将其构建缓存用于其他不经常更改的构建步骤。因为通常使用新的Docker映像为每个新版本的源代码构建,请尽可能晚在Dockerfile中将源代码添加到映像中。”
最后我要考虑的另一件事是the cache expiration time。
请记住,必须对其进行适当配置,以免丢失依赖项的任何更新,但不要在没有任何使用的情况下运行构建。
您可能会认为有用的更多链接(请记住,这些链接不是Google来源):
Docker documentation about Multi-stage Builds
Using Multi-Stage Builds to Simplify And Standardize Build Processes