docker buildx build 명령어를 사용하여 이미지 빌드 및 관리 방법

DockerBeginner
지금 연습하기

소개

이 랩에서는 docker buildx build 명령을 사용하여 Docker 이미지를 빌드하고 관리하는 실질적인 경험을 얻게 됩니다. 먼저, Dockerfile을 사용하여 이미지 지침을 정의하는 방법을 배우면서 기본 설정을 사용하여 간단한 이미지를 빌드하는 것으로 시작합니다.

기본 사항을 넘어, 빌드 인수를 활용하고 다단계 빌드 내에서 특정 단계를 타겟팅하는 것과 같은 고급 기능을 탐구할 것입니다. 또한 --cache-from--cache-to를 사용하여 빌드 시간을 최적화하기 위해 빌드 캐시를 효과적으로 관리하는 방법을 배우게 됩니다. 더 나아가, 이 랩에서는 멀티 플랫폼 이미지를 빌드하여 레지스트리에 푸시하는 방법을 안내하고, 빌드 프로세스 중에 보안적으로 시크릿과 SSH 에이전트를 노출하는 방법을 보여줍니다.

기본 설정을 사용하여 간단한 이미지 빌드

이 단계에서는 Dockerfile을 사용하여 간단한 Docker 이미지를 빌드하는 방법을 배웁니다. Dockerfile은 사용자가 이미지를 조립하기 위해 명령줄에서 호출할 수 있는 모든 명령을 포함하는 텍스트 문서입니다. Docker 는 Dockerfile에서 지침을 읽어 자동으로 이미지를 빌드할 수 있습니다.

먼저, 이 랩의 작업 디렉토리인 ~/project 디렉토리로 이동합니다.

cd ~/project

이제 간단한 Dockerfile을 만들어 보겠습니다. 이 Dockerfileubuntu 기본 이미지를 기반으로 이미지를 정의하고, 이 이미지에서 컨테이너가 실행될 때 "Hello, Docker!"를 출력합니다.

nano 편집기를 사용하여 ~/project 디렉토리에 Dockerfile이라는 파일을 만듭니다.

nano Dockerfile

다음 내용을 Dockerfile에 추가합니다.

FROM ubuntu:latest
CMD ["echo", "Hello, Docker!"]

이 간단한 Dockerfile을 자세히 살펴보겠습니다.

  • FROM ubuntu:latest: 이 지침은 새 이미지의 기본 이미지를 설정합니다. Docker Hub 에서 제공하는 최신 버전의 공식 Ubuntu 이미지를 사용하고 있습니다.
  • CMD ["echo", "Hello, Docker!"]: 이 지침은 이 이미지에서 컨테이너가 시작될 때 실행될 명령을 지정합니다. 이 경우, "Hello, Docker!" 인수를 사용하여 echo 명령을 실행합니다.

Ctrl + S를 눌러 파일을 저장하고, Ctrl + X를 눌러 nano 편집기를 종료합니다.

이제 Dockerfile이 있으므로 docker build 명령을 사용하여 이미지를 빌드할 수 있습니다. 명령 끝에 있는 .은 Docker 에게 현재 디렉토리 (~/project) 에서 Dockerfile을 찾도록 지시합니다. 또한 이미지를 my-hello-image와 같은 이름으로 태그할 것입니다.

docker build -t my-hello-image .

Docker 가 이미지를 레이어별로 빌드하고 있음을 나타내는 출력을 볼 수 있습니다. 먼저 시스템에 아직 없는 경우 ubuntu:latest 이미지를 가져온 다음 CMD 지침을 실행합니다.

빌드가 완료되면 docker images 명령을 사용하여 사용 가능한 이미지를 나열하여 이미지가 성공적으로 생성되었는지 확인할 수 있습니다.

docker images

출력에 my-hello-image가 나열되어야 합니다.

마지막으로, 새로 빌드된 이미지에서 컨테이너를 실행하여 CMD 지침의 출력을 확인해 보겠습니다.

docker run my-hello-image

터미널에 "Hello, Docker!" 출력이 표시되어야 합니다. 이는 이미지가 올바르게 빌드되었고 CMD 지침이 예상대로 작동하고 있음을 확인합니다.

빌드 인수 및 대상 스테이지 사용

이 단계에서는 더 유연하고 효율적인 빌드를 만들기 위해 Dockerfile에서 빌드 인수 (ARG) 와 대상 단계를 사용하는 방법을 배웁니다. 빌드 인수를 사용하면 빌드 프로세스에 변수를 전달할 수 있으며, 대상 단계를 사용하면 단일 Dockerfile 내에서 여러 빌드 단계를 정의하고 특정 단계만 빌드할 수 있습니다.

먼저, ~/project 디렉토리에 있는지 확인합니다.

cd ~/project

기존 Dockerfile을 수정하여 빌드 인수와 간단한 다단계 빌드를 포함해 보겠습니다. 인사 메시지에 대한 인수를 정의하고 두 번째 단계를 사용하여 첫 번째 단계에서 파일을 복사합니다.

nano를 사용하여 Dockerfile을 엽니다.

nano Dockerfile

기존 내용을 다음 내용으로 바꿉니다.

## Stage 1: Builder stage
FROM ubuntu:latest as builder
ARG GREETING="Hello from build argument!"
RUN echo $GREETING > /app/greeting.txt

## Stage 2: Final stage
FROM ubuntu:latest
COPY --from=builder /app/greeting.txt /greeting.txt
CMD ["cat", "/greeting.txt"]

변경 사항을 이해해 보겠습니다.

  • ARG GREETING="Hello from build argument!": 이 지침은 기본값을 가진 GREETING이라는 빌드 인수를 정의합니다. 빌드 프로세스 중에 이 기본값을 재정의할 수 있습니다.
  • FROM ubuntu:latest as builder: 이는 첫 번째 빌드 단계를 시작하고 이름을 builder로 지정합니다. 이는 다단계 빌드에 유용합니다.
  • RUN echo $GREETING > /app/greeting.txt: builder 단계에서 이 명령은 /app 디렉토리에 greeting.txt라는 파일을 생성하고 GREETING 인수의 값을 씁니다.
  • FROM ubuntu:latest: 이는 두 번째 빌드 단계를 시작합니다. 기본적으로 이것이 최종 이미지가 됩니다.
  • COPY --from=builder /app/greeting.txt /greeting.txt: 이 지침은 builder 단계에서 (특히 /app/greeting.txt에서) greeting.txt 파일을 현재 단계의 루트 디렉토리 (/) 로 복사합니다. 이것이 다단계 빌드에서 아티팩트를 단계 간에 전송하는 방법입니다.
  • CMD ["cat", "/greeting.txt"]: 이는 최종 이미지에서 컨테이너가 실행될 때 실행될 명령을 설정합니다. /greeting.txt 파일의 내용을 출력합니다.

Dockerfile을 저장하고 nano를 종료합니다.

이제 docker build 명령을 사용하여 이미지를 빌드해 보겠습니다. --build-arg 플래그를 사용하여 GREETING 인수에 대한 사용자 지정 값을 전달합니다. 또한 이 이미지를 my-arg-image로 태그합니다.

docker build --build-arg GREETING="Greetings from the command line!" -t my-arg-image .

출력을 관찰합니다. 제공된 빌드 인수를 사용하는 빌드 프로세스를 볼 수 있습니다.

빌드가 완료되면 이미지를 나열하여 my-arg-image가 있는지 확인합니다.

docker images

이제 my-arg-image에서 컨테이너를 실행하여 출력을 확인합니다.

docker run my-arg-image

"Greetings from the command line!"이 출력되어 빌드 인수가 사용되었음을 확인합니다.

다음으로, builder 단계만 빌드해 보겠습니다. 이는 최종 애플리케이션 없이 빌드 아티팩트를 포함하는 중간 이미지를 만드는 데 유용합니다. --target 플래그를 사용하여 단계 이름을 지정합니다.

docker build --target builder -t my-builder-stage .

이미지를 다시 나열합니다. 이제 my-arg-image 외에 my-builder-stage도 표시됩니다.

docker images

my-builder-stage에서 컨테이너를 실행하는 것은 최종 단계의 CMD 지침이 builder 단계에 포함되지 않기 때문에 my-arg-image와 동일한 출력을 생성하지 않습니다. 실행해 보고 어떤 일이 발생하는지 확인해 보겠습니다 (기본 명령이 없으므로 빠르게 시작하고 종료될 것입니다).

docker run my-builder-stage

이는 대상 단계를 통해 Dockerfile의 어떤 부분이 이미지로 빌드되는지 제어할 수 있음을 보여줍니다.

--cache-from 및 --cache-to 를 사용하여 빌드 캐시 관리

이 단계에서는 --cache-from--cache-to 플래그를 사용하여 Docker 빌드 캐시를 관리하는 방법을 배웁니다. 빌드 캐시는 이전 빌드의 레이어를 재사용하여 후속 빌드의 속도를 크게 높일 수 있습니다. --cache-from을 사용하면 캐시 소스로 사용할 이미지를 지정할 수 있으며, --cache-to를 사용하면 빌드 캐시를 지정된 위치 (예: 레지스트리 또는 로컬 디렉토리) 로 내보낼 수 있습니다.

먼저, ~/project 디렉토리에 있는지 확인합니다.

cd ~/project

캐시를 손상시킬 수 있는 변경 사항을 시뮬레이션하기 위해 Dockerfile을 약간 수정해 보겠습니다. 간단한 RUN 지침을 추가합니다.

nanoDockerfile을 엽니다.

nano Dockerfile

builder 단계에서 ARG 지침 뒤에 다음 줄을 추가합니다.

RUN echo "Adding a new layer"

업데이트된 Dockerfile은 다음과 같아야 합니다.

## Stage 1: Builder stage
FROM ubuntu:latest as builder
ARG GREETING="Hello from build argument!"
RUN echo "Adding a new layer"
RUN echo $GREETING > /app/greeting.txt

## Stage 2: Final stage
FROM ubuntu:latest
COPY --from=builder /app/greeting.txt /greeting.txt
CMD ["cat", "/greeting.txt"]

Dockerfile을 저장하고 nano를 종료합니다.

이제 특정 캐시 옵션을 사용하지 않고 이미지를 다시 빌드해 보겠습니다. Docker 는 사용 가능한 경우 로컬 캐시를 자동으로 사용합니다.

docker build -t my-cached-image .

새 지침을 추가했으므로 일부 레이어가 처음부터 빌드되어 후속 지침에 대한 캐시가 무효화되는 것을 볼 수 있습니다.

이제 이전에 빌드된 이미지를 캐시 소스로 사용하려는 시나리오를 시뮬레이션해 보겠습니다. 예를 들어 레지스트리 또는 다른 빌드에서 가져올 수 있습니다. 데모 목적으로 방금 빌드한 my-cached-image를 새 빌드의 캐시 소스로 사용합니다.

먼저, Dockerfile을 다시 약간 변경하여 또 다른 수정을 시뮬레이션해 보겠습니다.

Dockerfile을 엽니다.

nano Dockerfile

RUN 지침의 메시지를 변경합니다.

RUN echo "Adding another new layer"

업데이트된 Dockerfile은 다음과 같아야 합니다.

## Stage 1: Builder stage
FROM ubuntu:latest as builder
ARG GREETING="Hello from build argument!"
RUN echo "Adding another new layer"
RUN echo $GREETING > /app/greeting.txt

## Stage 2: Final stage
FROM ubuntu:latest
COPY --from=builder /app/greeting.txt /greeting.txt
CMD ["cat", "/greeting.txt"]

저장하고 nano를 종료합니다.

이제 이미지를 다시 빌드하지만 이번에는 --cache-from 플래그를 사용하여 my-cached-image를 캐시 소스로 지정합니다.

docker build --cache-from my-cached-image -t my-cached-image-from .

Docker 가 my-cached-image에서 레이어를 사용하려고 시도하는 것을 관찰해야 합니다. 첫 번째 RUN 지침에 해당하는 레이어는 지침이 변경되었으므로 다시 빌드될 가능성이 높지만, 일치하는 경우 후속 레이어는 캐시에서 가져올 수 있습니다.

--cache-to 플래그는 빌드 캐시를 내보내는 데 사용됩니다. 이는 CI/CD 파이프라인에서 빌드 간에 캐시를 공유하는 데 특히 유용합니다. --cache-to를 사용하려면 일반적으로 docker-container 드라이버와 같이 캐시 내보내기를 지원하는 빌드 드라이버를 사용해야 합니다.

먼저, buildx 와 함께 자주 사용되는 Docker Compose 를 설치해 보겠습니다.

sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

이제 buildx 빌더 인스턴스를 만들어 보겠습니다.

docker buildx create --use

이제 이미지를 빌드하고 캐시를 로컬 디렉토리로 내보내겠습니다. local 캐시 익스포터를 사용합니다.

docker buildx build --cache-to type=local,dest=./build-cache -t my-exported-cache-image . --load
  • docker buildx build: 빌드에 buildx 도구를 사용합니다.
  • --cache-to type=local,dest=./build-cache: 캐시를 현재 디렉토리의 build-cache라는 로컬 디렉토리로 내보냅니다.
  • -t my-exported-cache-image: 결과 이미지에 태그를 지정합니다.
  • . : 빌드 컨텍스트 (현재 디렉토리) 를 지정합니다.
  • --load: 빌드된 이미지를 로컬 Docker 이미지 캐시에 로드합니다.

빌드 및 캐시 내보내기를 나타내는 출력을 볼 수 있습니다. ~/project 디렉토리에 build-cache 디렉토리가 생성됩니다.

이제 깨끗한 빌드 환경을 시뮬레이션하고 내보낸 캐시를 사용하여 빌드해 보겠습니다. 먼저, 빌드한 이미지를 제거해 보겠습니다.

docker rmi my-cached-image my-cached-image-from my-exported-cache-image

이제 이미지를 다시 빌드하지만 이번에는 내보낸 캐시를 소스로 사용합니다.

docker buildx build --cache-from type=local,src=./build-cache -t my-imported-cache-image . --load
  • --cache-from type=local,src=./build-cache: 로컬 디렉토리 build-cache에서 캐시를 가져옵니다.

Docker 가 내보낸 캐시의 레이어를 사용하여 처음부터 빌드하는 것보다 빌드 프로세스의 속도를 크게 높이는 것을 관찰해야 합니다.

멀티 플랫폼 이미지 빌드 및 레지스트리에 푸시

이 단계에서는 여러 아키텍처 (예: linux/amd64linux/arm64) 에 대한 Docker 이미지를 빌드하고 컨테이너 레지스트리에 푸시하는 방법을 배웁니다. 멀티 플랫폼 이미지를 빌드하는 것은 애플리케이션이 다양한 유형의 하드웨어에서 실행될 수 있도록 하는 데 필수적입니다. 이전 단계에서 초기화한 Docker Buildx 를 사용합니다.

먼저, ~/project 디렉토리에 있는지 확인합니다.

cd ~/project

이 단계에서는 기존 Dockerfile을 사용합니다. linux/amd64linux/arm64 플랫폼 모두에 대한 이미지를 빌드해 보겠습니다. 이미지를 이름과 버전으로 태그합니다 (예: your-dockerhub-username/my-multi-platform-image:latest). your-dockerhub-username을 실제 Docker Hub 사용자 이름으로 바꿉니다. Docker Hub 계정이 없는 경우 무료로 만들 수 있습니다.

여러 플랫폼을 빌드하려면 docker buildx build와 함께 --platform 플래그를 사용합니다. 또한 결과 매니페스트 목록과 이미지를 레지스트리에 푸시하려면 --push 플래그를 사용해야 합니다.

docker buildx build --platform linux/amd64,linux/arm64 -t your-dockerhub-username/my-multi-platform-image:latest . --push

참고: 이 명령을 실행하려면 아직 로그인하지 않은 경우 Docker Hub 에 로그인해야 합니다. 필요한 경우 별도의 터미널 세션에서 docker login 명령을 사용하여 로그인할 수 있습니다.

docker login

메시지가 표시되면 Docker Hub 사용자 이름과 비밀번호를 입력합니다.

로그인한 후 docker buildx build 명령을 다시 실행합니다.

빌드 프로세스는 지정된 각 아키텍처에 대해 이미지를 빌드하므로 단일 플랫폼 빌드보다 오래 걸립니다. 빌드가 완료되면 Buildx 는 각 플랫폼에 대한 이미지를 참조하는 매니페스트 목록을 생성하고 모든 것을 지정된 Docker Hub 리포지토리에 푸시합니다.

웹 브라우저에서 Docker Hub 리포지토리를 방문하여 멀티 플랫폼 이미지가 푸시되었는지 확인할 수 있습니다. latest 태그가 있는 my-multi-platform-image가 표시되고 "Tags" 탭에서 여러 아키텍처를 지원하는 것을 볼 수 있습니다.

또는 docker buildx imagetools inspect 명령을 사용하여 방금 푸시한 매니페스트 목록을 검사할 수 있습니다. your-dockerhub-username을 사용자 이름으로 바꿉니다.

docker buildx imagetools inspect your-dockerhub-username/my-multi-platform-image:latest

출력에는 매니페스트 목록과 해당 목록이 가리키는 서로 다른 이미지 (각 아키텍처 포함) 가 표시됩니다.

이는 Docker 이미지를 더욱 다재다능하게 만들어 다양한 CPU 아키텍처에서 실행할 수 있는 이미지를 빌드하고 푸시하는 방법을 보여줍니다.

빌드에 시크릿 및 SSH 에이전트 노출

이 단계에서는 Buildx 를 사용하여 시크릿과 SSH 에이전트를 Docker 빌드 프로세스에 안전하게 노출하는 방법을 배웁니다. 이는 빌드에서 개인 리포지토리에 액세스하고, 개인 패키지를 설치하거나, Dockerfile에 민감한 정보를 직접 포함하지 않고 인증이 필요한 외부 서비스와 상호 작용해야 하는 시나리오에 매우 중요합니다.

먼저, ~/project 디렉토리에 있는지 확인합니다.

cd ~/project

빌드 중에 시크릿을 사용하는 방법을 보여주기 위해 Dockerfile을 수정합니다. 이 예제에서는 더미 시크릿 파일을 만들고 빌드 중에 해당 내용을 읽습니다.

~/project 디렉토리에 mysecret.txt라는 파일을 만들고 일부 시크릿 콘텐츠를 추가합니다.

echo "This is a secret message!" > ~/project/mysecret.txt

이제 nanoDockerfile을 엽니다.

nano Dockerfile

--mount=type=secret 플래그를 사용하여 시크릿에 액세스하는 새로운 RUN 지침을 builder 단계에 추가합니다.

## Stage 1: Builder stage
FROM ubuntu:latest as builder
ARG GREETING="Hello from build argument!"
RUN echo "Adding another new layer"
RUN echo $GREETING > /app/greeting.txt
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret > /app/secret_content.txt

## Stage 2: Final stage
FROM ubuntu:latest
COPY --from=builder /app/greeting.txt /greeting.txt
COPY --from=builder /app/secret_content.txt /secret_content.txt
CMD ["cat", "/greeting.txt", "/secret_content.txt"]

새로운 지침을 이해해 보겠습니다.

  • RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret > /app/secret_content.txt: 이 지침은 시크릿을 빌드 컨테이너에 마운트합니다.
    • --mount=type=secret: 시크릿을 마운트하고 있음을 지정합니다.
    • id=mysecret: 빌드 중에 제공할 시크릿의 ID 입니다.
    • cat /run/secrets/mysecret: 빌드 컨테이너 내에서 시크릿은 /run/secrets/mysecret에서 사용할 수 있습니다. cat을 사용하여 해당 내용을 읽습니다.
    • > /app/secret_content.txt: 시크릿 내용을 빌더 단계 내의 /app 디렉토리에 있는 secret_content.txt라는 파일로 리디렉션합니다.

또한 최종 단계에 COPY 지침을 추가하여 secret_content.txt 파일을 빌더 단계에서 복사했습니다.

Dockerfile을 저장하고 nano를 종료합니다.

이제 docker buildx build를 사용하여 이미지를 빌드하고 --secret 플래그를 사용하여 시크릿을 제공합니다.

docker buildx build --secret id=mysecret,src=~/project/mysecret.txt -t my-secret-image . --load
  • --secret id=mysecret,src=~/project/mysecret.txt: 이 플래그는 빌드에 시크릿을 제공합니다.
    • id=mysecret: Dockerfile에 지정된 ID 와 일치합니다.
    • src=~/project/mysecret.txt: 로컬 머신에서 시크릿 파일의 경로를 지정합니다.

이제 빌드 프로세스는 RUN --mount=type=secret... 지침을 실행하는 동안 mysecret.txt의 내용에 액세스할 수 있습니다. 시크릿 내용은 최종 이미지 레이어에 저장되지 않습니다.

빌드가 완료된 후 이미지에서 컨테이너를 실행합니다.

docker run my-secret-image

콘솔에 인사 메시지와 시크릿 파일의 내용이 모두 출력되는 것을 볼 수 있습니다.

이제 SSH 에이전트를 빌드에 노출하는 방법을 보여드리겠습니다. 이는 빌드 프로세스 중에 개인 Git 리포지토리를 복제하는 데 유용합니다.

먼저, SSH 에이전트가 실행 중이고 키가 로드되었는지 확인합니다. 일반적으로 ssh-add -l로 확인할 수 있습니다. 에이전트가 실행 중이지 않거나 키가 추가되지 않은 경우 에이전트를 시작하고 키를 추가해야 할 수 있습니다.

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa ## Replace with your SSH key path if different

이제 SSH 에이전트를 사용하도록 Dockerfile을 수정합니다. SSH 를 사용하여 (존재하지 않는) 개인 리포지토리를 복제하려는 RUN 지침을 추가합니다.

Dockerfile을 엽니다.

nano Dockerfile

--mount=type=ssh 플래그를 사용하는 새로운 RUN 지침을 builder 단계에 추가합니다.

## Stage 1: Builder stage
FROM ubuntu:latest as builder
ARG GREETING="Hello from build argument!"
RUN echo "Adding another new layer"
RUN echo $GREETING > /app/greeting.txt
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret > /app/secret_content.txt
RUN --mount=type=ssh git clone git@github.com:your-username/your-private-repo.git || echo "Skipping git clone as this is a demo"

## Stage 2: Final stage
FROM ubuntu:latest
COPY --from=builder /app/greeting.txt /greeting.txt
COPY --from=builder /app/secret_content.txt /secret_content.txt
CMD ["cat", "/greeting.txt", "/secret_content.txt"]

참고: your-username/your-private-repo.git을 개인 리포지토리 URL 의 자리 표시자로 바꿉니다. 리포지토리가 없거나 액세스 권한이 없는 경우 빌드가 실패하지 않도록 || echo "Skipping git clone as this is a demo" 부분이 추가되었습니다.

Dockerfile을 저장하고 nano를 종료합니다.

이제 docker buildx build를 사용하여 이미지를 빌드하고 --ssh 플래그를 사용하여 SSH 에이전트에 대한 액세스를 제공합니다.

docker buildx build --ssh default -t my-ssh-image . --load
  • --ssh default: 이 플래그는 기본 SSH 에이전트를 빌드에 노출합니다.

빌드하는 동안 RUN --mount=type=ssh... 지침은 Git 서버로 인증하기 위해 SSH 에이전트를 사용할 수 있습니다.

빌드가 완료된 후 이미지를 실행할 수 있지만 git clone 작업이 건너뛰었을 가능성이 높으므로 출력은 이전과 동일합니다.

docker run my-ssh-image

이는 Buildx 를 사용하여 Docker 빌드 프로세스 중에 시크릿과 SSH 에이전트를 안전하게 사용하는 방법을 보여주며, 민감한 정보가 이미지에 포함되는 것을 방지합니다.

요약

이 랩에서는 Dockerfile을 사용하여 Docker 이미지를 빌드하는 기본 사항을 배웠습니다. Ubuntu 를 기반으로 하는 이미지를 정의하고 기본 명령을 실행하는 간단한 Dockerfile을 생성하는 것으로 시작했습니다. 그런 다음 docker build 명령을 사용하여 이 이미지를 빌드하고 Docker 가 Dockerfile의 지침을 레이어별로 처리하는 방법과 결과 이미지를 태그하는 방법을 이해했습니다.

기본 사항을 바탕으로 docker buildx build 명령의 보다 고급 기능을 탐색했습니다. 여기에는 빌드 인수를 활용하여 동적 값을 빌드 프로세스에 전달하고, 멀티 스테이지 빌드 내에서 대상 스테이지를 활용하여 이미지 크기 및 빌드 시간을 최적화하는 것이 포함되었습니다. 또한 후속 빌드의 속도를 높이기 위해 --cache-from--cache-to를 사용하여 빌드 캐시를 효과적으로 관리하는 방법을 배웠습니다. 또한, 이미지가 서로 다른 아키텍처에서 실행될 수 있도록 멀티 플랫폼 이미지를 빌드하고 이러한 멀티 플랫폼 이미지를 컨테이너 레지스트리에 푸시하는 경험을 얻었습니다. 마지막으로, 빌드 프로세스 중에 시크릿을 안전하게 노출하고 SSH 에이전트를 활용하여 이미지 빌드의 보안과 유연성을 향상시키는 방법을 배웠습니다.