소개

Docker는 애플리케이션을 개발, 패키징, 배포하는 방식을 혁신했다. 개발부터 프로덕션까지 애플리케이션이 실행되는 일관된 환경을 제공하여 "내 컴퓨터에서는 되는데" 문제를 줄여준다. Docker가 도입한 가장 강력한 기능 중 하나는 Multi-Stage Build다. 이 기능은 번거로움 없이 가볍고 효율적인 컨테이너를 만들 수 있게 해준다. 이 블로그 글에서는 Docker Multi-Stage Build, 그 이점, 그리고 모범 사례를 깊이 탐구한다. 또한 개념을 설명하기 위한 예제 Dockerfile도 제공한다.

Docker Multi-Stage Build란 무엇인가?

Docker Multi-Stage Build는 Dockerfile에서 여러 FROM 문을 사용할 수 있게 해주는 기능이다. 각 FROM 문은 다른 베이스 이미지를 사용할 수 있으며 빌드의 새로운 단계를 시작한다. 한 단계에서 다른 단계로 아티팩트를 선택적으로 복사할 수 있으며, 최종 이미지에 필요하지 않은 모든 것을 남겨둘 수 있다. 이를 통해 빌드와 패키징 프로세스를 서로 다른 단계로 분리하여 더 작고 효율적인 이미지를 만들 수 있다.

Docker Multi-Stage Build를 사용해야 하는 이유

Multi-Stage Build가 도입되기 전에는 가벼운 Docker 이미지를 만드는 것이 다소 번거로웠다. 애플리케이션 빌드와 실행을 위해 별도의 Dockerfile을 만들거나, 프로덕션 이미지에 불필요한 도구를 설치해야 했다. Multi-Stage Build는 하나의 Dockerfile로 효율적인 이미지를 만들 수 있게 해 이러한 문제를 해결한다. Docker Multi-Stage Build를 사용해야 하는 이유는 다음과 같다:

  1. 더 작은 이미지 크기: 빌드 단계에서 최종 이미지로 필요한 파일만 복사함으로써 Docker 이미지 크기를 크게 줄일 수 있다. 더 작은 이미지는 레지스트리에서 푸시와 풀이 더 빠르고 디스크 공간을 덜 사용한다.
  2. 관심사 분리: Multi-Stage Build를 사용하면 빌드 타임 의존성과 런타임 의존성을 분리할 수 있다. 이는 Dockerfile을 더 읽기 쉽고 유지 관리하기 쉽게 만든다.
  3. 보안: 더 작은 이미지는 더 작은 공격 표면을 가진다. 불필요한 도구와 파일을 제외함으로써 보안 취약점의 가능성을 줄인다.

모범 사례

  1. 구체적인 베이스 이미지 사용: 각 단계마다 해당 단계에 필요한 것만 포함하는 가장 구체적인 베이스 이미지를 사용하라. 예를 들어 Node.js 애플리케이션이 포함된 빌드 단계에는 Node.js 이미지를, 가벼운 최종 단계에는 Alpine 이미지를 사용하라.
  2. 레이어 생성 최적화: Docker는 레이어로 이미지를 빌드한다. 빌드를 더 빠르게 하고 이미지를 더 작게 만들려면 &&를 사용하여 명령을 결합하여 레이어 수를 최소화하라.
  3. 사용 후 정리: 빌드 단계에서 사용이 끝난 불필요한 파일과 아티팩트를 정리하라. 이렇게 하면 빌드 캐시가 더 작아지고 빨라진다.

예제 Dockerfile

다음은 Node.js 애플리케이션을 위한 Multi-Stage Build를 보여주는 예제 Dockerfile이다:

Dockerfile

—- Base Node —-

FROM node:14 AS base WORKDIR /usr/src/app COPY package*.json ./

—- Dependencies —-

FROM base AS dependencies RUN npm install

—- Test —-

run linters, setup and tests

FROM dependencies AS test COPY . . RUN npm run test

—- Build —-

FROM dependencies AS build COPY . . RUN npm run build

—- Release —-

FROM node:14-alpine AS release WORKDIR /usr/src/app COPY –from=build /usr/src/app/dist ./dist EXPOSE 8080 CMD [“node”, “dist/index.js”]

이 Dockerfile에는 base, dependencies, test, build, release의 다섯 단계가 있다. base 단계는 package.json 파일을 복사한다. dependencies 단계는 Node 모듈을 설치한다. test 단계는 테스트를 실행한다. build 단계는 애플리케이션을 빌드한다. 마지막으로 release 단계는 프로덕션에서 사용될 최종 이미지를 생성한다. 필요한 파일만 최종 이미지에 복사되어 더 작고 효율적인 이미지가 만들어진다.

결론

Docker Multi-Stage Build는 효율적인 Docker 이미지를 만드는 강력한 도구다. 빌드 환경과 런타임 환경을 분리하고, 이미지 크기를 줄이며, 보안을 향상시킬 수 있다. 모범 사례를 따르고 잘 구조화된 Dockerfile을 사용함으로써 이 기능을 최대한 활용할 수 있다. 즐거운 Docker 라이프 되길!