Tôi hiểu câu hỏi này đã có một số câu trả lời phổ biến. Nhưng có một cách mới hơn để lưu tệp vào bộ nhớ cache cho trình quản lý gói. Tôi nghĩ rằng nó có thể là một câu trả lời tốt trong tương lai khi BuildKit trở nên tiêu chuẩn hơn.
Kể từ Docker 18.09 có hỗ trợ thử nghiệm cho BuildKit . BuildKit bổ sung hỗ trợ cho một số tính năng mới trong Dockerfile bao gồm hỗ trợ thử nghiệm để gắn khối lượng bên ngoài vào RUN
các bước. Điều này cho phép chúng tôi tạo bộ nhớ đệm cho những thứ như $HOME/.cache/pip/
.
Chúng tôi sẽ sử dụng requirements.txt
tệp sau làm ví dụ:
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
Một ví dụ điển hình của Python Dockerfile
có thể giống như sau:
FROM python:3.7
WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/
RUN pip install -r requirements.txt
COPY . /usr/src/app
Với BuildKit được bật bằng cách sử dụng DOCKER_BUILDKIT
biến môi trường, chúng ta có thể tạo pip
bước chưa được lưu trong khoảng 65 giây:
$ 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
Bây giờ, chúng ta hãy thêm tiêu đề thử nghiệm và sửa đổi RUN
bước để lưu vào bộ nhớ cache các gói Python:
# 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
Hãy tiếp tục và thực hiện một bản dựng khác ngay bây giờ. Nó sẽ mất cùng một khoảng thời gian. Nhưng lần này nó đang lưu vào bộ nhớ đệm các gói Python trong mount bộ đệm mới của chúng tôi:
$ 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
Khoảng 60 giây. Tương tự như bản dựng đầu tiên của chúng tôi.
Thực hiện một thay đổi nhỏ đối với requirements.txt
(chẳng hạn như thêm một dòng mới giữa hai gói) để buộc vô hiệu bộ nhớ cache và chạy lại:
$ 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
Chỉ khoảng 16 giây!
Chúng tôi đang nhận được tốc độ này vì chúng tôi không còn tải xuống tất cả các gói Python nữa. Chúng đã được trình quản lý gói pip
lưu vào bộ nhớ cache ( trong trường hợp này) và được lưu trữ trong ổ đĩa gắn kết bộ nhớ cache. Khối lượng gắn kết được cung cấp cho bước chạy để pip
có thể sử dụng lại các gói đã tải xuống của chúng tôi. Điều này xảy ra bên ngoài bất kỳ bộ nhớ đệm lớp Docker nào .
Lợi nhuận sẽ tốt hơn nhiều khi lớn hơn requirements.txt
.
Ghi chú:
- Đây là cú pháp Dockerfile thử nghiệm và nên được xử lý như vậy. Bạn có thể không muốn xây dựng với điều này trong sản xuất tại thời điểm này.
Nội dung BuildKit không hoạt động trong Docker Compose hoặc các công cụ khác sử dụng trực tiếp API Docker vào lúc này. Hiện đã có hỗ trợ cho việc này trong Docker Compose kể từ 1.25.0. Xem Làm cách nào để kích hoạt BuildKit với docker-soạn?
- Không có bất kỳ giao diện trực tiếp nào để quản lý bộ nhớ cache vào lúc này. Nó được thanh lọc khi bạn làm a
docker system prune -a
.
Hy vọng rằng những tính năng này sẽ được đưa vào Docker để xây dựng và BuildKit sẽ trở thành mặc định. Nếu / khi điều đó xảy ra, tôi sẽ cố gắng cập nhật câu trả lời này.