Comment éviter de réinstaller les paquets lors de la construction de Docker image pour Python projets?
Mon Dockerfile est quelque chose comme
FROM my/base
ADD . /srv
RUN pip install -r requirements.txt
RUN python setup.py install
ENTRYPOINT ["run_server"]
Chaque fois que j'construire une nouvelle image, dépendances doivent être réinstallés, qui peut être très lente dans ma région.
Un sens, je pense à cache
les paquets qui ont été installés à l'est de remplacer la my/base
image avec de nouvelles images comme ceci:
docker build -t new_image_1 .
docker tag new_image_1 my/base
Alors, la prochaine fois je construire avec ce Dockerfile, mon/base a déjà des packages installés.
Mais cette solution a deux problèmes:
- Il n'est pas toujours possible de remplacer une image de base
- L'image de base grandir et de plus grand que de nouvelles images sont superposées sur elle
Alors quelle meilleure solution pourrais-je utiliser pour résoudre ce problème?
EDIT##:
Quelques informations sur le menu fixe sur ma machine:
☁ test docker version
Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070
☁ test docker info
Containers: 0
Images: 56
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Dirs: 56
Execution Driver: native-0.2
Kernel Version: 3.13.0-29-generic
WARNING: No swap limit support
- Ne vous supprimez des images intermédiaires après avoir terminé la construction de votre image?
- Bien sûr que non, mais ce n'est pas pertinent parce que quand j'ai de la reconstruction d'une image, je suis toujours en se basant sur l'origine
my/base
Vous devez vous connecter pour publier un commentaire.
Essayer de construire avec ci-dessous Dockerfile.
Si il y a quelques changements sur
.
(votre projet), docker sauterpip install
ligne à l'aide du cache.Docker seulement exécuter
pip install
sur la compilation lorsque vous modifiez requirements.txt fichier.J'écris simple
Hello, World!
programme.Ci-dessous est de sortie.
- Je mettre à jour seulement run.py et essayer de construire à nouveau.
Ci-dessous est de sortie.
Comme vous pouvez le voir ci-dessus, docker utiliser créer une cache. Et je l'ai mise à jour requirements.txt cette fois.
Ci-dessous est de sortie.
Et docker n'utilisez pas de construire cache. Si cela ne fonctionne pas, vérifiez votre menu fixe version.
ADD
instruction, d'une invalidation de la mémoire cache.ADD ./requirements.txt /srv/requirements.txt
), puis docker devez utiliser le cache. Voir ajouter seciton sur Dockerfile document.ADD requirements.txt /srv
avant d'exécuter le programme pep (RUN pip install -r requirements.txt
), et ajouter tous les autres fichiers après en cours d'exécution du pip. Par conséquent, ils devraient être dans l'ordre suivant: (1)ADD requirements.txt /srv
; (2)RUN pip install -r requirements.txt
; (3)ADD . /srv
COPY . .
(ouADD
) à la fin, après avoir installé toutes les dépendances.À minimiser l'activité du réseau, vous pourriez
pip
à un répertoire de cache sur votre ordinateur hôte.Exécuter votre conteneur docker avec votre hôte pip répertoire de cache montés dans le récipient du pip répertoire de cache.
docker run
commande devrait ressembler à ceci:Puis dans votre Dockerfile installer vos exigences en tant que partie de
ENTRYPOINT
instruction (ouCMD
déclaration) au lieu d'unRUN
de commande. Ceci est important, car, comme on l'a souligné dans les commentaires) le support n'est pas disponible lors de la construction de l'image (quandRUN
instructions sont exécutées). Docker fichier devrait ressembler à ceci:Probablement que c'est mieux si l'hôte par défaut du système pip répertoire sera utilisé comme un cache (par exemple,
$HOME/.cache/pip/
sur Linux ou$HOME/Library/Caches/pip/
sur OSX), tout comme je l'ai suggéré dans l'exempledocker run
commande.Je comprends cette question a certaines réponses déjà. Mais il existe une nouvelle façon de fichiers de cache pour les gestionnaires de paquets. Je pense qu'il pourrait être une bonne réponse à l'avenir, lorsque BuildKit devient de plus en plus la norme.
De Docker 18.09 il y a un support expérimental pour BuildKit. BuildKit ajoute le support pour certaines nouvelles fonctionnalités dans le Dockerfile, y compris support expérimental pour le montage des volumes externes en
RUN
étapes. Cela nous permet de créer des caches pour des choses comme$HOME/.cache/pip/
.Nous allons utiliser la suite
requirements.txt
fichier comme un exemple:Un exemple typique Python
Dockerfile
pourrait ressembler à:Avec BuildKit activé à l'aide de la
DOCKER_BUILDKIT
variable d'environnement on peut construire le cachepip
étape dans environ 65 secondes:Maintenant, nous allons ajouter le expérimentales en-tête et de modifier le
RUN
étape pour mettre en cache les paquets Python:Aller de l'avant et faire un autre construire maintenant. Il devrait prendre la même quantité de temps. Mais cette fois, c'est la mise en cache les paquets Python dans notre nouveau cache de la monture:
Environ 60 secondes. Semblable à notre première compilation.
Faire un petit changement pour le
requirements.txt
(comme l'ajout d'une nouvelle ligne entre deux paquets) pour forcer une invalidation de cache et de courir à nouveau:Seulement environ 16 secondes!
Nous obtenons cette accélération parce que nous ne sommes plus à télécharger tous les paquets Python. Ils ont été mis en cache par le gestionnaire de paquets (
pip
dans ce cas) et stocké dans un cache de montage de volume. Le volume de montage est fournie pour l'exécution de l'étape de sorte quepip
de réutiliser notre déjà les paquets téléchargés. Ce qui se passe à l'extérieur d'un Docker de la couche de mise en cache.Les gains devrait être beaucoup mieux sur les grandes
requirements.txt
.Notes:
docker system prune -a
.Espérons que ces fonctionnalités dans le Panneau pour la construction et l'BuildKit devient la valeur par défaut. Si /quand cela arrive, je vais essayer de mettre à jour cette réponse.
J'ai trouvé que la meilleure façon est de simplement ajouter le Python site-packages répertoire comme un volume.
De cette façon, je peux juste pip installer de nouvelles bibliothèques sans avoir à faire une reconstruction complète.
MODIFIER: Ignorer cette réponse, jkukul de réponse ci-dessus a fonctionné pour moi. Mon intention était de mettre en cache les site-packages dossier. Qui aurait ressemblé à quelque chose de plus comme:
Cache le dossier de téléchargement est beaucoup plus propre si. Aussi les caches, les roues, de sorte qu'il réalise correctement la tâche.