Saya mengerti pertanyaan ini sudah memiliki beberapa jawaban populer. Tetapi ada cara yang lebih baru untuk menyimpan file dalam cache untuk manajer paket. Saya rasa ini bisa menjadi jawaban yang bagus di masa depan ketika BuildKit menjadi lebih standar.
Mulai Docker 18.09 ada dukungan eksperimental untuk BuildKit . BuildKit menambahkan dukungan untuk beberapa fitur baru di Dockerfile termasuk dukungan eksperimental untuk memasang volume eksternal ke dalam beberapa RUNlangkah. Ini memungkinkan kami membuat cache untuk hal-hal seperti $HOME/.cache/pip/.
Kami akan menggunakan requirements.txtfile berikut sebagai contoh:
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
Contoh tipikal Python Dockerfilemungkin terlihat seperti:
FROM python:3.7
WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/
RUN pip install -r requirements.txt
COPY . /usr/src/app
Dengan BuildKit diaktifkan menggunakan DOCKER_BUILDKITvariabel lingkungan, kita dapat membuat piplangkah yang tidak di -cache dalam waktu sekitar 65 detik:
$ 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
Sekarang, mari kita tambahkan tajuk eksperimental dan modifikasi RUNlangkah untuk menyimpan paket Python ke cache:
# 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
Silakan dan lakukan build lain sekarang. Ini harus memakan waktu yang sama. Tapi kali ini cache paket Python di cache mount baru kami:
$ 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
Sekitar 60 detik. Mirip dengan build pertama kami.
Buat perubahan kecil pada requirements.txt(seperti menambahkan baris baru di antara dua paket) untuk memaksa pembatalan cache dan dijalankan lagi:
$ 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
Hanya sekitar 16 detik!
Kami mendapatkan percepatan ini karena kami tidak lagi mengunduh semua paket Python. Mereka di-cache oleh manajer paket ( pipdalam hal ini) dan disimpan dalam mount volume cache. Volume mount disediakan untuk langkah run sehingga pipdapat menggunakan kembali paket yang sudah kami unduh. Ini terjadi di luar cache lapisan Docker .
Keuntungannya harus jauh lebih baik pada yang lebih besar requirements.txt.
Catatan:
- Ini adalah sintaks Dockerfile eksperimental dan harus diperlakukan seperti itu. Anda mungkin tidak ingin membangun dengan ini dalam produksi saat ini.
Item BuildKit tidak berfungsi di bawah Docker Compose atau alat lain yang secara langsung menggunakan API Docker saat ini. Sekarang ada dukungan untuk ini di Docker Compose mulai 1.25.0. Lihat Bagaimana Anda mengaktifkan BuildKit dengan docker-compose?
- Tidak ada antarmuka langsung untuk mengelola cache saat ini. Itu dihapus ketika Anda melakukan a
docker system prune -a.
Mudah-mudahan, fitur-fitur ini akan membuatnya menjadi Docker untuk dibangun dan BuildKit akan menjadi defaultnya. Jika / ketika itu terjadi, saya akan mencoba memperbarui jawaban ini.