이 질문에 이미 인기있는 답변이 있음을 이해합니다. 그러나 패키지 관리자를 위해 파일을 캐시하는 새로운 방법이 있습니다. 앞으로 BuildKit이 더 표준이 될 때 좋은 대답이 될 수 있다고 생각합니다.
Docker 18.09부터 BuildKit에 대한 실험적인 지원이 있습니다 . BuildKit은 외부 볼륨 을 RUN
단계 로 마운트하기위한 실험적 지원을 포함하여 Dockerfile의 몇 가지 새로운 기능에 대한 지원을 추가 합니다. 이것은 우리가 $HOME/.cache/pip/
.
다음 requirements.txt
파일을 예로 사용하겠습니다 .
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
일반적인 예제 Python Dockerfile
은 다음과 같습니다.
FROM python:3.7
WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/
RUN pip install -r requirements.txt
COPY . /usr/src/app
DOCKER_BUILDKIT
환경 변수를 사용하여 BuildKit을 활성화하면 pip
약 65 초 안에 캐시되지 않은 단계를 빌드 할 수 있습니다 .
$ 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
이제 실험 헤더를 추가 RUN
하고 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
이제 다른 빌드를 수행하십시오. 같은 시간이 걸립니다. 그러나 이번에는 새로운 캐시 마운트에서 Python 패키지를 캐싱합니다.
$ 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
약 60 초. 첫 번째 빌드와 유사합니다.
requirements.txt
캐시를 강제로 무효화하고 다시 실행하려면를 약간 변경 (예 : 두 패키지 사이에 새 줄 추가)합니다.
$ 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
약 16 초!
더 이상 모든 Python 패키지를 다운로드하지 않기 때문에 속도가 빨라집니다. 패키지 관리자 ( pip
이 경우)에 의해 캐시되고 캐시 볼륨 마운트에 저장되었습니다. pip
이미 다운로드 한 패키지를 재사용 할 수 있도록 볼륨 마운트가 실행 단계에 제공 됩니다. 이것은 Docker 계층 캐싱 외부에서 발생합니다 .
더 큰 이득은 훨씬 더 나을 것입니다 requirements.txt
.
노트:
- 이것은 실험적인 Dockerfile 구문이며 이와 같이 취급해야합니다. 현재 프로덕션 환경에서 이것을 빌드하고 싶지 않을 수 있습니다.
BuildKit 항목은 Docker Compose 또는 현재 Docker API를 직접 사용하는 다른 도구에서는 작동하지 않습니다. 이제 1.25.0부터 Docker Compose에서이를 지원합니다. docker-compose로 BuildKit을 어떻게 활성화합니까?를 참조하십시오 .
- 현재 캐시를 관리하기위한 직접적인 인터페이스가 없습니다. 를 수행하면 제거됩니다
docker system prune -a
.
바라건대, 이러한 기능은 빌드를 위해 Docker로 만들고 BuildKit이 기본값이 될 것입니다. 그럴 경우이 답변을 업데이트하려고합니다.