0
votes

Déploiement avec Build Caching à l'aide de Docker sur Heroku

J'essaie d'optimiser une application docker sur Heroku pour mettre en cache les dépendances installées entre les versions. Jusqu'à présent, je n'ai pas pu obtenir de versions ultérieures pour utiliser une forme de mise en cache. Par exemple, en utilisant le Dockerfile suivant:

build:
  docker:
    web: Dockerfile

Si docker build -t test . localement plusieurs fois je vois:

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

Déploiement sur Heroku plusieurs fois (avec des commits vides), je vois:

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

Mon fichier heroku.yml est:

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

Est-il possible d'utiliser la mise en cache des couches avec le docker Heroku pour accélérer les builds?


2 commentaires

Avez-vous étiqueté et publié l'image du docker? Si oui à quel registre? Voir devcenter.heroku.com/articles/ ... Avez-vous spécifié manuellement la commande docker build sur Heroku ou est-elle automatiquement déduite? Sur le hub docker que je fais: docker build --pull --cache-from $(repo):amd64-dev -f Dockerfile.amd64 -t $(repo):amd64-dev . suivi d'un docker push $(repo):amd64-dev .


Heroku construit l'image docker dans le cadre du processus de déploiement.


3 Réponses :


0
votes

Peut-être qu'au lieu d'utiliser la commande COPY , vous pouvez ADD les fichiers.

Cela devrait contourner le mécanisme de mise en cache Dockerfile pour éviter d'invalider l'intégralité de votre cache lorsque vous modifiez du code.

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

PS Je ne suis pas très familier avec le système de docker de Heroku, mais idéalement ADD est meilleur que COPY et fonctionne bien avec la mise en cache.


3 commentaires

Merci d'avoir répondu, mais ne voyant aucune différence entre COPY et ADD. Aussi - selon le guide du docker, je pense que COPY est préférable à moins d'utiliser certaines fonctions étendues offertes par ADD: docs.docker.com/develop/develop-images / ...


Peut-être que cela pourrait aider (j'ai adapté ma réponse d'ici): blog.heroku.com / ...


De plus, vous avez raison à propos de l'instruction COPY ... elle est préférable, mais pas à cause d'une différence de performances ou de mise en cache - docs.docker.com/develop/develop-images / ...



0
votes

Pouvez-vous vérifier qu'après la construction, l'espace de travail est en cours d'effacement ou ce que cela peut être l'une des raisons pour lesquelles le cache docker est invalidé.


1 commentaires

Je ne sais pas ce que cela signifie. Que dois-je vérifier dans les journaux pour voir cela?



1
votes

Heroku se déploie généralement avec git . Vous poussez votre code source. Heroku détecte le type de votre projet et sélectionne le pack de construction approprié. Heroku construit un conteneur à l'aide du pack de construction. Le pack de construction sait comment le faire efficacement, en mettant en cache les dépendances, etc. Heroku déploie ensuite ce conteneur. Vous n'avez pas besoin d'écrire un Dockerfile.

Heroku prend en charge le déploiement avec docker pour les personnes qui ont besoin de plus de contrôle sur le conteneur. Ces builds s'exécutent dans un environnement propre et le comportement que vous voyez est correct. La mise en cache d'anciennes couches docker entre les versions de production est délicate. La même chaîne de commande (par exemple apt-get install ) exécutée ultérieurement peut donner des résultats différents.

Si une partie de votre Dockerfile prend beaucoup de temps, vous devrez peut-être attendre trop longtemps pour mettre à jour un déploiement au moment du développement. Ensuite, vous pouvez utiliser un flux différent dans lequel vous créez l'image localement et la transmettez au registre de conteneurs Heroku lorsque vous souhaitez qu'elle soit déployée.

Si vous êtes intéressé par ce dernier flux, jetez un œil aux packs de build natifs du cloud qui vous permettent de créer le conteneur pour votre code source à l'aide du pack CLI.


1 commentaires

Merci pour le flip de réponse. Pour clarifier - il semble que Heroku ne prend pas en charge la mise en cache de couches lors de la création d'une image Docker au meilleur de vos connaissances? La raison de mes efforts est de comparer les problèmes de performances avec les déploiements utilisant les packs de build traditionnels.