使用Docker在Heroku上部署Build Caching



我正在尝试优化Heroku上的docker应用程序,以缓存构建之间已安装的依赖项。到目前为止,我还无法让后续的构建使用任何形式的缓存。例如,使用以下Dockerfile:

FROM ruby:2.7.2-alpine
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install

如果我在本地多次运行docker build -t test .,我会看到:

docker build -t test .
Sending build context to Docker daemon  92.16kB
Step 1/4 : FROM ruby:2.7.2-alpine
---> 79f5adf3c887
Step 2/4 : WORKDIR /app
---> Using cache
---> 1c42ebe94fa4
Step 3/4 : COPY Gemfile Gemfile.lock ./
---> Using cache
---> 626c3092389f
Step 4/4 : RUN bundle install
---> Using cache
---> 15e0dce9151b
Successfully built 15e0dce9151b
Successfully tagged test:latest

多次部署到Heroku(带有空提交(我看到:

Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 697 bytes | 697.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Compressing source files... done.
remote: Building source:
remote: === Fetching app code
remote: 
remote: === Building web (Dockerfile)
remote: Sending build context to Docker daemon  7.168kB
remote: Step 1/4 : FROM ruby:2.7.2-alpine
remote: 2.7.2-alpine: Pulling from library/ruby
remote: 188c0c94c7c5: Pulling fs layer
remote: ba0772c8cbe1: Pulling fs layer
remote: dcff69af93dc: Pulling fs layer
remote: 16507e0b6111: Pulling fs layer
remote: 6aadfa8ff2a8: Pulling fs layer
remote: 16507e0b6111: Waiting
remote: 6aadfa8ff2a8: Waiting
remote: dcff69af93dc: Verifying Checksum
remote: dcff69af93dc: Download complete
remote: ba0772c8cbe1: Verifying Checksum
remote: ba0772c8cbe1: Download complete
remote: 188c0c94c7c5: Verifying Checksum
remote: 188c0c94c7c5: Download complete
remote: 6aadfa8ff2a8: Verifying Checksum
remote: 6aadfa8ff2a8: Download complete
remote: 16507e0b6111: Verifying Checksum
remote: 16507e0b6111: Download complete
remote: 188c0c94c7c5: Pull complete
remote: ba0772c8cbe1: Pull complete
remote: dcff69af93dc: Pull complete
remote: 16507e0b6111: Pull complete
remote: 6aadfa8ff2a8: Pull complete
remote: Digest: sha256:f9f332eece9188d10abb30ff6b109a1b0fee9f3e82683df8df8bf81be8121567
remote: Status: Downloaded newer image for ruby:2.7.2-alpine
remote:  ---> 79f5adf3c887
remote: Step 2/4 : WORKDIR /app
remote:  ---> Running in e8d12e411b82
remote: Removing intermediate container e8d12e411b82
remote:  ---> d5833157511c
remote: Step 3/4 : COPY Gemfile Gemfile.lock ./
remote:  ---> 47f0942ba73c
remote: Step 4/4 : RUN bundle install
remote:  ---> Running in 15b1359b8240
remote: Fetching gem metadata from https://rubygems.org/....
remote: Using bundler 2.1.4
remote: Fetching ruby2_keywords 0.0.2
remote: Installing ruby2_keywords 0.0.2
remote: Fetching mustermann 1.1.1
remote: Installing mustermann 1.1.1
remote: Fetching rack 2.2.3
remote: Installing rack 2.2.3
remote: Fetching rack-protection 2.1.0
remote: Installing rack-protection 2.1.0
remote: Fetching tilt 2.0.10
remote: Installing tilt 2.0.10
remote: Fetching sinatra 2.1.0
remote: Installing sinatra 2.1.0
remote: Bundle complete! 1 Gemfile dependency, 7 gems now installed.
remote: Use `bundle info [gemname]` to see where a bundled gem is installed.
remote: Removing intermediate container 15b1359b8240
remote:  ---> 318addc210bd
remote: Successfully built 318addc210bd
remote: Successfully tagged 31d653df6d02eb931fff2c0be8a4cc35b829ea54:latest
remote: 
remote: === Pushing web (Dockerfile)
remote: Tagged image "31d653df6d02eb931fff2c0be8a4cc35b829ea54" as "registry.heroku.com/secret-sierra-97497/web"
remote: The push refers to repository [registry.heroku.com/secret-sierra-97497/web]
remote: 0f8d2b92cc43: Preparing
remote: 1fff78e61e17: Preparing
remote: eebe8de04d9e: Preparing
remote: 410b5fd47642: Preparing
remote: 12b703c99815: Preparing
remote: e44bb72897d4: Preparing
remote: 720dc6953f4e: Preparing
remote: ace0eda3e3be: Preparing
remote: e44bb72897d4: Waiting
remote: 720dc6953f4e: Waiting
remote: ace0eda3e3be: Waiting
remote: 12b703c99815: Layer already exists
remote: 410b5fd47642: Layer already exists
remote: e44bb72897d4: Layer already exists
remote: 720dc6953f4e: Layer already exists
remote: ace0eda3e3be: Layer already exists
remote: 1fff78e61e17: Pushed
remote: eebe8de04d9e: Pushed
remote: 0f8d2b92cc43: Pushed
remote: latest: digest: sha256:11214585c68599a907c5855a213dc3d0121d9f535cb9be8ec8ed6a6ba3998913 size: 1989
remote: 
remote: Verifying deploy... done.
To https://git.heroku.com/secret-sierra-97497.git
933054c..19603ae  master -> master

我的heroku.yml文件是:

build:
docker:
web: Dockerfile

有可能使用Heroku docker的层缓存来加快构建速度吗?

Heroku通常使用git进行部署。你推送你的源代码。Heroku探查您的项目类型并选择适当的构建包。Heroku使用构建包构建一个容器。构建包知道如何高效地实现这一点,缓存依赖关系等等。然后Heroku部署该容器。你不需要写Dockerfile。

Heroku支持为那些需要更多控制容器的人部署docker。这些构建在干净的环境中运行,您看到的行为是正确的。在生产构建之间缓存旧的docker层是很棘手的。稍后执行的相同命令串(例如apt-get install(可以产生不同的结果。

如果Dockerfile的某些部分非常耗时,您可能会发现在开发时需要等待太长时间才能更新部署。然后,您可以使用不同的流,在本地构建映像,并在需要部署映像时将其推送到Heroku容器注册表。

如果您对最后一个流程感兴趣,请查看云原生构建包,它允许您使用packCLI为源代码构建容器。

也许不使用COPY命令,而是可以ADD文件。

这应该解决Dockerfile缓存机制的问题,以防止在更改某些代码时使整个缓存无效。

FROM ruby:2.7.2-alpine
ADD Gemfile /app/
ADD Gemfile.lock  /app/
RUN bundle install

PS我不太熟悉Heroku的docker系统,但理想情况下ADD比COPY更好,并且可以很好地使用缓存

最新更新