Bu sorunun zaten bazı popüler cevapları olduğunu anlıyorum. Ancak, paket yöneticileri için dosyaları önbelleğe almanın daha yeni bir yolu var. Bence, gelecekte BuildKit daha standart hale geldiğinde iyi bir cevap olabilir.
Docker 18.09'dan itibaren BuildKit için deneysel destek vardır . BuildKit dahil Dockerfile bazı yeni özellikler için destek ekler dış hacimleri monte etmek için deneysel destek içine RUNadımlar. Bu, gibi şeyler için önbellek oluşturmamızı sağlar $HOME/.cache/pip/.
Aşağıdaki requirements.txtdosyayı örnek olarak kullanacağız :
Click==7.0
Django==2.2.3
django-appconf==1.0.3
django-compressor==2.3
django-debug-toolbar==2.0
django-filter==2.2.0
django-reversion==3.0.4
django-rq==2.1.0
pytz==2019.1
rcssmin==1.0.6
redis==3.3.4
rjsmin==1.1.0
rq==1.1.0
six==1.12.0
sqlparse==0.3.0
Tipik bir Python örneği Dockerfileşöyle görünebilir:
FROM python:3.7
WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/
RUN pip install -r requirements.txt
COPY . /usr/src/app
BuildKit DOCKER_BUILDKITortam değişkenini kullanarak etkinleştirildiğinde , önbelleğe alınmamış pipadımı yaklaşık 65 saniyede oluşturabiliriz:
$ export DOCKER_BUILDKIT=1
$ docker build -t test .
[+] Building 65.6s (10/10) FINISHED
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 120B 0.0s
=> [internal] load metadata for docker.io/library/python:3.7 0.5s
=> CACHED [1/4] FROM docker.io/library/python:3.7@sha256:6eaf19442c358afc24834a6b17a3728a45c129de7703d8583392a138ecbdb092 0.0s
=> [internal] load build context 0.6s
=> => transferring context: 899.99kB 0.6s
=> CACHED [internal] helper image for file operations 0.0s
=> [2/4] COPY requirements.txt /usr/src/app/ 0.5s
=> [3/4] RUN pip install -r requirements.txt 61.3s
=> [4/4] COPY . /usr/src/app 1.3s
=> exporting to image 1.2s
=> => exporting layers 1.2s
=> => writing image sha256:d66a2720e81530029bf1c2cb98fb3aee0cffc2f4ea2aa2a0760a30fb718d7f83 0.0s
=> => naming to docker.io/library/test 0.0s
Şimdi deneysel başlığı ekleyelim RUNve Python paketlerini önbelleğe alma adımını değiştirelim :
# syntax=docker/dockerfile:experimental
FROM python:3.7
WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt
COPY . /usr/src/app
Devam edin ve şimdi başka bir yapı yapın. Aynı miktarda zaman almalı. Ancak bu sefer Python paketlerini yeni önbellek bağlantımızda önbelleğe alıyor:
$ docker build -t pythontest .
[+] Building 60.3s (14/14) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 120B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> resolve image config for docker.io/docker/dockerfile:experimental 0.5s
=> CACHED docker-image://docker.io/docker/dockerfile:experimental@sha256:9022e911101f01b2854c7a4b2c77f524b998891941da55208e71c0335e6e82c3 0.0s
=> [internal] load .dockerignore 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 120B 0.0s
=> [internal] load metadata for docker.io/library/python:3.7 0.5s
=> CACHED [1/4] FROM docker.io/library/python:3.7@sha256:6eaf19442c358afc24834a6b17a3728a45c129de7703d8583392a138ecbdb092 0.0s
=> [internal] load build context 0.7s
=> => transferring context: 899.99kB 0.6s
=> CACHED [internal] helper image for file operations 0.0s
=> [2/4] COPY requirements.txt /usr/src/app/ 0.6s
=> [3/4] RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt 53.3s
=> [4/4] COPY . /usr/src/app 2.6s
=> exporting to image 1.2s
=> => exporting layers 1.2s
=> => writing image sha256:0b035548712c1c9e1c80d4a86169c5c1f9e94437e124ea09e90aea82f45c2afc 0.0s
=> => naming to docker.io/library/test 0.0s
Yaklaşık 60 saniye. İlk yapımıza benzer.
requirements.txtÖnbellek geçersiz kılmaya zorlamak ve tekrar çalıştırmak için (iki paket arasına yeni bir satır eklemek gibi) üzerinde küçük bir değişiklik yapın :
$ docker build -t pythontest .
[+] Building 15.9s (14/14) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 120B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> resolve image config for docker.io/docker/dockerfile:experimental 1.1s
=> CACHED docker-image://docker.io/docker/dockerfile:experimental@sha256:9022e911101f01b2854c7a4b2c77f524b998891941da55208e71c0335e6e82c3 0.0s
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 120B 0.0s
=> [internal] load .dockerignore 0.0s
=> [internal] load metadata for docker.io/library/python:3.7 0.5s
=> CACHED [1/4] FROM docker.io/library/python:3.7@sha256:6eaf19442c358afc24834a6b17a3728a45c129de7703d8583392a138ecbdb092 0.0s
=> CACHED [internal] helper image for file operations 0.0s
=> [internal] load build context 0.7s
=> => transferring context: 899.99kB 0.7s
=> [2/4] COPY requirements.txt /usr/src/app/ 0.6s
=> [3/4] RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt 8.8s
=> [4/4] COPY . /usr/src/app 2.1s
=> exporting to image 1.1s
=> => exporting layers 1.1s
=> => writing image sha256:fc84cd45482a70e8de48bfd6489e5421532c2dd02aaa3e1e49a290a3dfb9df7c 0.0s
=> => naming to docker.io/library/test 0.0s
Sadece yaklaşık 16 saniye!
Bu hızlanmayı alıyoruz çünkü artık tüm Python paketlerini indirmiyoruz. Paket yöneticisi tarafından önbelleğe alındı ( pipbu durumda) ve bir önbellek birimi yuvasında saklandılar. Birim bağlama, pipzaten indirilmiş paketlerimizi yeniden kullanabilmek için çalıştırma adımına sağlanır . Bu, herhangi bir Docker katmanı önbelleğe alma işleminin dışında gerçekleşir .
Kazançlar daha büyük olduğunda çok daha iyi olmalı requirements.txt.
Notlar:
- Bu deneysel Dockerfile sözdizimidir ve bu şekilde ele alınmalıdır. Şu anda üretimde bununla inşa etmek istemeyebilirsiniz.
BuildKit öğeleri, şu anda Docker Compose veya Docker API'yi doğrudan kullanan diğer araçlar altında çalışmıyor. 1.25.0'dan itibaren Docker Compose'da artık bunun için destek var. Bkz Eğer liman işçisi-oluşturmadeneyimine ile BuildKit nasıl etkinleştirebilirim?
- Şu anda önbelleği yönetmek için herhangi bir doğrudan arayüz bulunmamaktadır. Yaptığınızda temizlenir a
docker system prune -a.
Umarım, bu özellikler onu oluşturmak için Docker'a dönüştürür ve BuildKit varsayılan olur. Bu olursa / olduğunda bu cevabı güncellemeye çalışacağım.