- 빌드 서버를 따로 두면 개발팀과 빌드 서버의 모든 도구를 같은 버전으로 사용해야 한다.
- 이 경우 빌드 툴체인을 한 번에 패키징해서 공유할 수 있다면 편리하다.
- 개발에 필요한 모든 도구를 배포하는 Dockerfile 스크립트를 작성한 다음 이를 이미지로 만든다.
멀티 스테이지 빌드를 적용한 Dockerfile 스크립트
- 빌드가 여러 단계로 나뉘는 멀티 스테이지 빌드를 적용한 것
- 각 빌드 단계는 FROM 인스트럭션으로 시작된다.
- 최종 산출물은 마지막 단계의 내용물을 담은 도커 이미지
- 각 빌드 단계는 독립적으로 실행되지만, 앞선 단계에서 만들어진 디렉터리나 파일을 복사할 수 있다.
- 어느 한 단계에서라도 명령이 실패하면 전체 빌드가 실패한다.
- RUN 인스트럭션은 빌드 중에 컨테이너 안에서 명령을 실행한 다음 그 결과를 이미지 레이어에 저장하는 기능을 한다.
- RUN 인스트럭션에서 실행할 수 있는 명령어는 FROM 인스트럭션에서 지정한 이미지에서 실행할 수 있는 것이어야 한다.
001) FROM diamol/base AS build-stage
002) RUN echo 'Building...' > /build.txt
003)
004) FROM diamol/base AS test-stage
005) COPY --from=build-stage /build.txt /build.txt
006) RUN echo 'Testing...' >> /build.txt
007)
008) FROM diamol/base
009) COPY --from=test-stage /build.txt /build.txt
010) CMD cat /build.txt
멀티 스테이지 Dockerfile 스크립트 빌드
001) ➜ docker build -t build-stage .
002) [+] Building 4.4s (10/10) FINISHED
003) => [internal] load build definition from Dockerfile 0.0s
004) => => transferring dockerfile: 302B 0.0s
005) => [internal] load .dockerignore 0.0s
006) => => transferring context: 2B 0.0s
007) => [internal] load metadata for docker.io/diamol/base:latest 3.5s
008) => [auth] diamol/base:pull token for registry-1.docker.io 0.0s
009) => [build-stage 1/2] FROM docker.io/diamol/base@sha256:787fe221a14f46b55e224ea0436aca77d345c3ded400aaf6cd40125e247f35c7 0.5s
010) => => resolve docker.io/diamol/base@sha256:787fe221a14f46b55e224ea0436aca77d345c3ded400aaf6cd40125e247f35c7 0.0s
011) => => sha256:787fe221a14f46b55e224ea0436aca77d345c3ded400aaf6cd40125e247f35c7 1.40kB / 1.40kB 0.0s
012) => => sha256:bd5e8ce69bca67190f789625870f8130d67069c4761b36ed7ecfa6dcbc6fdfd7 738B / 738B 0.0s
013) => => sha256:e65ed3e91e579a862befe0d866ffe1e3377d64245c9e9fd82fffaf9e3c961f49 1.65kB / 1.65kB 0.0s
014) => => sha256:941f399634ec37b35e6764d0e6cf350593652f06f76586d45ddfc0d77de7a701 2.69MB / 2.69MB 0.3s
015) => => sha256:716aca3e500c7c2254eeeb07df8d83bbff63f52d35080a800a21c250f9f1f2b2 829.71kB / 829.71kB 0.3s
016) => => extracting sha256:941f399634ec37b35e6764d0e6cf350593652f06f76586d45ddfc0d77de7a701 0.1s
017) => => extracting sha256:716aca3e500c7c2254eeeb07df8d83bbff63f52d35080a800a21c250f9f1f2b2 0.0s
018) => [build-stage 2/2] RUN echo 'Building...' > /build.txt 0.2s
019) => [test-stage 2/3] COPY --from=build-stage /build.txt /build.txt 0.0s
020) => [test-stage 3/3] RUN echo 'Testing...' >> /build.txt 0.2s
021) => [stage-2 2/2] COPY --from=test-stage /build.txt /build.txt 0.0s
022) => exporting to image 0.0s
023) => => exporting layers 0.0s
024) => => writing image sha256:ce804607c335e406af4a00f1e9386de7b7c201c2f33f5478e1c3dca379e3821b 0.0s
025) => => naming to docker.io/library/build-stage
- 009~018: build-stage 단계, 이 단계에서 build.txt 파일이 생성된다.
- 019~020: test-stage 단계, 앞서 생성한 build.txt 파일을 이미지에 추가
-
021~022: stage 단계, 최종 결과물이 될 이미지를 생성
-
build-stage 단계에서는 빌드 도구가 설치된 기반 이미지를 사용, 로컬 컴퓨터에서 소스 코드를 복사해 넣고, build 명령을 실행
- test-stage 단계에서는 단위 테스트 프레임워크가 설치된 기반 이미지를 사용하여 앞서 빌드한 바이너리를 복사해 간 다음 단위 테스트 실행
- stage 단계 에서는 애플리케이션을 실행할 런타임이 들어 있는 기반 이미지로 시작. 앞선 단계에서 성공적으로 빌드와 테스트까지 마친 바이너리를 이 이미지에 복사해 넣는다.
이런 방법으로 애플리케이션의 진정한 이식성을 확보할 수 있다. 도커만 갖춰진다면 컨테이너를 통해 어떤 환경에서든 애플리케이션을 빌드하거나 실행할 수 있다.