具有多个阶段的Dockerfile重建上一个阶段的部分

发布于 2025-02-04 06:22:06 字数 2181 浏览 3 评论 0原文

我有这个多阶段的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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

め七分饶幸 2025-02-11 06:22:06

由于这些命令的docker缓存检查文件和目录的哈希,因此可以轻松地从复制 ADD 命令中轻松地将Docker Cache无效。

该哈希包括每个文件的内容,甚至是文件上的权限。因此,如果其中任何一个通过一个字节更改,则哈希将有所不同,并且Docker将有一个缓存失误,迫使该行重新运行。

从第一个缓存失误的点开始,所有其余的线都需要重建,因为上一层现在是新的,并且尚未用于运行以下任何步骤。

The docker cache can be easily invalidated from a COPY or ADD 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文