4.1.Dockerfile이 있는데 빌드 서버가 필요할까?

  • 빌드 서버를 따로 두면 개발팀과 빌드 서버의 모든 도구를 같은 버전으로 사용해야 한다.
  • 이 경우 빌드 툴체인을 한 번에 패키징해서 공유할 수 있다면 편리하다.
  • 개발에 필요한 모든 도구를 배포하는 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
  1. 009~018: build-stage 단계, 이 단계에서 build.txt 파일이 생성된다.
  2. 019~020: test-stage 단계, 앞서 생성한 build.txt 파일을 이미지에 추가
  3. 021~022: stage 단계, 최종 결과물이 될 이미지를 생성

  4. build-stage 단계에서는 빌드 도구가 설치된 기반 이미지를 사용, 로컬 컴퓨터에서 소스 코드를 복사해 넣고, build 명령을 실행

  5. test-stage 단계에서는 단위 테스트 프레임워크가 설치된 기반 이미지를 사용하여 앞서 빌드한 바이너리를 복사해 간 다음 단위 테스트 실행
  6. stage 단계 에서는 애플리케이션을 실행할 런타임이 들어 있는 기반 이미지로 시작. 앞선 단계에서 성공적으로 빌드와 테스트까지 마친 바이너리를 이 이미지에 복사해 넣는다.

이런 방법으로 애플리케이션의 진정한 이식성을 확보할 수 있다. 도커만 갖춰진다면 컨테이너를 통해 어떤 환경에서든 애플리케이션을 빌드하거나 실행할 수 있다.

links

social