Docker-in-Docker 빌드를 Docker 레이어 캐시로 더 빠르게 만들기

Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated

Docker-in-Docker를 사용할 때마다 빌드를 만들 때마다 Docker는 이미지의 모든 레이어를 다운로드합니다.

최근 버전의 Docker(Docker 1.13 이상)는 docker build 단계에서 캐시로 이전 이미지를 사용할 수 있습니다.

이것은 빌드 프로세스를 상당히 가속화합니다.

Docker 27.0.1 이상에서는 기본 docker 빌드 드라이버가 containerd 이미지 스토어가 활성화된 경우에만 캐시 백엔드를 지원합니다.

Docker 27.0.1 이상에서 Docker 캐싱을 사용하려면 다음 중 하나를 수행하십시오:

  • Docker 데몬 구성에서 containerd 이미지 스토어를 활성화합니다.
  • 다른 빌드 드라이버를 선택합니다.

자세한 내용은 캐시 저장소 백엔드를 참조하십시오.

Docker 캐싱 작동 원리

docker build를 실행할 때 Dockerfile의 각 명령은 레이어를 생성합니다.

이 레이어는 캐시로 유지되며 변경 사항이 없으면 재사용할 수 있습니다.

하나의 레이어에 변경이 발생하면 모든 후속 레이어가 다시 생성됩니다.

docker build 명령의 캐시 소스로 사용할 태그가 있는 이미지를 지정하려면 --cache-from 인수를 사용하십시오.

여러 --cache-from 인수를 사용하여 여러 이미지를 캐시 소스로 지정할 수 있습니다.

--cache-from 인수와 함께 사용되는 모든 이미지는 캐시 소스로 사용되기 전에 docker pull로 가져와야 합니다.

Docker 캐싱 예시

이 예제 .gitlab-ci.yml 파일은 기본 docker build 명령과 함께 inline 캐시 백엔드를 사용하는 방법을 보여줍니다.

보다 고급 캐시 옵션에 대해서는 docker buildx build 명령 및 캐시 옵션을 참조하십시오.

default:
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

variables:
  # TLS 사용 https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: "/certs"

build:
  stage: build
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker build --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - docker push $CI_REGISTRY_IMAGE:latest

build 작업의 script 섹션에서:

  1. 첫 번째 명령은 레지스트리에서 이미지를 가져오려고 시도합니다. 이는 docker build 명령의 캐시로 사용될 수 있습니다.

  2. 두 번째 명령은 가져온 이미지를 캐시로 사용하여 Docker 이미지를 빌드합니다(사용 가능한 경우 --cache-from $CI_REGISTRY_IMAGE:latest 인수를 참조) 그리고 태그를 지정합니다.

    --build-arg BUILDKIT_INLINE_CACHE=1은 Docker에게 인라인 캐싱을 사용하라고 지시하며, 이는 빌드 캐시를 이미지 자체에 포함합니다.

  3. 마지막 두 명령은 태그가 붙은 Docker 이미지를 컨테이너 레지스트리에 푸시하여 이후 빌드의 캐시로 사용할 수 있도록 합니다.