在 Heroku 上使用 Docker 进行构建缓存部署

Kev*_*tre 2 heroku

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

FROM ruby:2.7.2-alpine
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
Run Code Online (Sandbox Code Playgroud)

如果我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
Run Code Online (Sandbox Code Playgroud)

多次部署到 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
Run Code Online (Sandbox Code Playgroud)

我的 heroku.yml 文件是:

FROM ruby:2.7.2-alpine
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
Run Code Online (Sandbox Code Playgroud)

是否可以使用 Heroku docker 的层缓存来加速构建?

flu*_*lup 5

Heroku 通常使用 git 进行部署。你推送你​​的源代码。Heroku 会嗅出您的项目类型并选择适当的构建包。Heroku 使用构建包构建容器。构建包知道如何有效地做到这一点,缓存依赖项等。然后 Heroku 部署该容器。您不需要编写 Dockerfile。

Heroku 支持使用 docker 进行部署,适合需要对容器进行更多控制的人员。这些构建在干净的环境中运行,并且您看到的行为是正确的。在生产版本之间缓存旧的 docker 层是很棘手的。apt-get install稍后执行相同的命令字符串(例如)可能会产生不同的结果。

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

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