Docker Buildx is a CLI plugin that extends the docker command with the full support of the features provided by 
Moby BuildKit
 builder toolkit. It provides the same user experience as docker build with many new features like creating scoped builder instances and building against multiple nodes concurrently.

도커 buildx는 도커 빌더로 moby buildkit을 사용하게 해주는 CLI 플러그인입니다.

scope builder instance, building against multiple nodes concurrently 등 여러 기능이 많습니다. 오늘 기준(21. 9. 4.) buildx, buildkit 둘 다 0.x 버전으로 아직 experimental 기능이긴 한데 쓸만합니다.


github actions 워크플로에서 docker build -> ecr push 한다고 했을 때 기본적으로 캐싱이 되지 않기 때문에 매 워크플로에서 모든 레이어를 계속 만들게 됩니다.

buildx를 이용하면 워크플로에서 도커 레이어를 캐싱해놓을 수 있는데 예제 워크플로 파일을 한번 보겠습니다.

on:
  push:
    branches:
      - main

name: Build and push Docker image to ECR

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      # (1)
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      # (2)
      - name: Cache Docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-buildx-

      # ... Configure Docker repository ...

      - name: Build and push
        id: docker-build
        uses: docker/build-push-action@v2
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPOSITORY_NAME }}
          IMAGE_TAG: latest
        with:
          push: true
          tags: "${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.IMAGE_TAG }}"
          # (3)
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new

      # (4)
      - name: Move cache
        run: |
          rm -rf /tmp/.buildx-cache
          mv /tmp/.buildx-cache-new /tmp/.buildx-cache

      # ...

기존 워크플로에서 4가지 부분을 추가했습니다.

  • (1) docker buildx 설치
  • (2) actions/cache를 사용해 캐시 받아오기
  • (3) docker/build-push-action에 'cache-from', 'cache-to' 설정
  • (4) 레이어 캐싱

설정이 별로 어렵지 않습니다. 중요한건 (4) 부분인데, 깃허브에서 각 리파지토리는 5GB까지만 캐시를 보관할 수 있어서 수동으로 이전 캐시 지우고, 새로운 캐시를 옮겨놓는 과정이 저 부분입니다.

(참고: https://github.com/actions/cache#cache-limits)

 

 

캐싱 전 후 비교

캐싱 전, 후 비교

캐싱 전후 비교하면 위와 같은데, 순수한 도커 빌드 시간만 보면 대략 절반으로 줄었습니다.

물론 cache + post cache 시간이 좀 걸리긴 하는데, 빌드 시간이 더 오래 걸리는 환경일수록 캐싱의 효과가 더 큽니다

제 도커 이미지는 단순히 python + django + 기타등등이라 모든 레이어를 다 받고 빌드해도 1~2분의 시간밖에 안 걸렸지만 프로덕션 환경이라면 더 오래 걸리겠죠?

지금은 퇴사한 상태라서 프로덕션 상태에서 테스트 해볼게 없네요...;

 

 

Reference

반응형