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 RUN
adımlar. Bu, gibi şeyler için önbellek oluşturmamızı sağlar $HOME/.cache/pip/
.
Aşağıdaki requirements.txt
dosyayı ö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_BUILDKIT
ortam değişkenini kullanarak etkinleştirildiğinde , önbelleğe alınmamış pip
adı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 RUN
ve 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ı ( pip
bu durumda) ve bir önbellek birimi yuvasında saklandılar. Birim bağlama, pip
zaten 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.