具有多个阶段的Dockerfile重建上一个阶段的部分
我有这个多阶段的Dockerfile:
FROM ruby:2.7.6 as base
ENV RAILS_ENV production
RUN apt-get update
RUN apt-get install -y \
nodejs \
npm \
vim
RUN npm install -g yarn
COPY . /app
WORKDIR /app
RUN gem install bundler
RUN bundle config set --local deployment 'true'
RUN bundle config set --local without 'development test'
RUN bundle
RUN DB_ADAPTER=nulldb bundle exec rake assets:precompile
FROM base as app
COPY . /app
WORKDIR /app
RUN gem install bundler
RUN bundle
RUN DB_ADAPTER=nulldb bundle exec rake assets:precompile
ENTRYPOINT ["/bin/bash", "-l", "-c"]
我构建base
with:
docker build --target base -t base .
然后app
with:
docker build --target app -t app .
非常简单。 App
之前的步骤很慢,我想缓存它们。
通常(尽管并非总是 - 不知道为什么)当我构建应用
时,它将在base
构建中的第一个副本后构建步骤。为什么这是?为什么不只是从base
图像开始并构建后来的步骤?
$ docker build --target app -t fapp .
Step 1/18 : FROM ruby:2.7.6 as base
---> f5dd208fb679
Step 2/18 : ENV RAILS_ENV production
---> Using cache
---> 1891c50dd23b
Step 3/18 : RUN apt-get update
---> Using cache
---> 2e8e284f77ec
Step 4/18 : RUN apt-get install -y nodejs npm vim
---> Using cache
---> 70695d86c467
Step 5/18 : RUN npm install -g yarn
---> Using cache
---> 706a007e43c6
Step 6/18 : COPY . /app
---> ad3eb2821641
Step 7/18 : WORKDIR /app
---> Running in 7a7f83850b35
Removing intermediate container 7a7f83850b35
---> f9b1984c059a
Step 8/18 : RUN gem install bundler
---> Running in 29c9929d887d
Successfully installed bundler-2.3.15
1 gem installed
Removing intermediate container 29c9929d887d
---> 619dc2797660
Step 9/18 : RUN bundle config set --local deployment 'true'
---> Running in 36c4e27ae841
Removing intermediate container 36c4e27ae841
---> 33d6e03834b9
Step 10/18 : RUN bundle config set --local without 'development test'
---> Running in 94afe6d016e9
Removing intermediate container 94afe6d016e9
---> 90796cebb446
Step 11/18 : RUN bundle
---> Running in 9ea7167d9aff
I have this multistage Dockerfile:
FROM ruby:2.7.6 as base
ENV RAILS_ENV production
RUN apt-get update
RUN apt-get install -y \
nodejs \
npm \
vim
RUN npm install -g yarn
COPY . /app
WORKDIR /app
RUN gem install bundler
RUN bundle config set --local deployment 'true'
RUN bundle config set --local without 'development test'
RUN bundle
RUN DB_ADAPTER=nulldb bundle exec rake assets:precompile
FROM base as app
COPY . /app
WORKDIR /app
RUN gem install bundler
RUN bundle
RUN DB_ADAPTER=nulldb bundle exec rake assets:precompile
ENTRYPOINT ["/bin/bash", "-l", "-c"]
I build base
with:
docker build --target base -t base .
Then app
with:
docker build --target app -t app .
Pretty straight forward. The steps before app
are slow, and I want to cache them.
Frequently (though not always - and no idea why) when I build app
It will build steps after the first COPY in the base
build. Why is this? Why isn't it just starting from the base
image and building the later steps?
$ docker build --target app -t fapp .
Step 1/18 : FROM ruby:2.7.6 as base
---> f5dd208fb679
Step 2/18 : ENV RAILS_ENV production
---> Using cache
---> 1891c50dd23b
Step 3/18 : RUN apt-get update
---> Using cache
---> 2e8e284f77ec
Step 4/18 : RUN apt-get install -y nodejs npm vim
---> Using cache
---> 70695d86c467
Step 5/18 : RUN npm install -g yarn
---> Using cache
---> 706a007e43c6
Step 6/18 : COPY . /app
---> ad3eb2821641
Step 7/18 : WORKDIR /app
---> Running in 7a7f83850b35
Removing intermediate container 7a7f83850b35
---> f9b1984c059a
Step 8/18 : RUN gem install bundler
---> Running in 29c9929d887d
Successfully installed bundler-2.3.15
1 gem installed
Removing intermediate container 29c9929d887d
---> 619dc2797660
Step 9/18 : RUN bundle config set --local deployment 'true'
---> Running in 36c4e27ae841
Removing intermediate container 36c4e27ae841
---> 33d6e03834b9
Step 10/18 : RUN bundle config set --local without 'development test'
---> Running in 94afe6d016e9
Removing intermediate container 94afe6d016e9
---> 90796cebb446
Step 11/18 : RUN bundle
---> Running in 9ea7167d9aff
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于这些命令的docker缓存检查文件和目录的哈希,因此可以轻松地从
复制
ADD 命令中轻松地将Docker Cache无效。该哈希包括每个文件的内容,甚至是文件上的权限。因此,如果其中任何一个通过一个字节更改,则哈希将有所不同,并且Docker将有一个缓存失误,迫使该行重新运行。
从第一个缓存失误的点开始,所有其余的线都需要重建,因为上一层现在是新的,并且尚未用于运行以下任何步骤。
The docker cache can be easily invalidated from a
COPY
orADD
command, since the docker cache for these commands checks a hash of the files and directories.Included in that hash are the contents of every file, and even the permissions on the files. So if any of these changed by a single byte, the hash will be different and docker will have a cache miss, forcing the line to be rerun.
From the point of the first cache miss, all remaining lines will need to be rebuilt since the preceding layer is now new and has not be used to run any of the following steps.