- 도커 컴포즈에 웹 애플리케이션과 API 서비스를 정의, 이들 이미지 항목에는 환경 변수를 사용
- 여기 사용된 환경 변수에는 기본값을 의미하는
:-
문법이 사용됐다.
001) version: "3.7"
002)
003) services:
004) numbers-api:
005) image: ${REGISTRY:-docker.io}/diamol/ch11-numbers-api:v3-build-${BUILD_NUMBER:-local}
006) networks:
007) - app-net
008)
009) numbers-web:
010) image: ${REGISTRY:-docker.io}/diamol/ch11-numbers-web:v3-build-${BUILD_NUMBER:-local}
011) environment:
012) - RngApi__Url=http://numbers-api/rng
013) depends_on:
014) - numbers-api
015) networks:
016) - app-net
-
005: 환경변수 REGISTRY 가 없다면 docker.io 를 기본값으로 사용
-
이 패턴을 사용하면 같은 결과물로 CI 파이프라인과 개발자 빌드를 매끄럽게 동시에 지원할 수 있다.
- 개발자가 빌드한 API 이미지에는 환경 변수가 정의돼 있지 않을 것이므로 이 이미지의 이미지 태그는
docker.io/diamol/ch11-numbers-api:v3-build-local
이 된다. - 그러나 docker.io는 도커 허브의 도메인이므로 생략할 수 있기 때문에
diamol/ch11-numbers-api:v3-build-local
로 보인다. - 반면 젠킨스에서 같은 이미지를 빌드하면 로컬 도커 레지스트리의 도메인과 빌드 작업 번호가 환경 변수로 정의돼 있기 때문에 이미지 태그는
registry.local:5000/diamol/ch11-numbers-api:v3-build-2
가 된다. - 이미지 이름을 유연하게 결정하도록 하는 설정은 CI 설정에서 중요한 부분이다.
실습 로컬 컴퓨터에서도 CI 빌드 파이프라인과 같은 단계를 거쳐 애플리케이션을 빌드할 수 있다. 터미널 창을 열고 이번 장의 예제 코드 디렉터리로 이동한 후 다음과 같이 도커 컴포즈를 실행해 애플리케이션을 빌드하라.
001) cd ./ch11/exercises
002)
003) # 두 이미지를 빌드
004) docker-compose -f docker-compose.yml -f docker-compose-build.yml build
005) => exporting to image 0.0s
006) => => naming to docker.io/diamol/ch11-numbers-api:v3-build-local 0.0s
007) => exporting to image 0.0s
008) => => naming to docker.io/diamol/ch11-numbers-web:v3-build-local 0.0s
009)
010) # 웹 애플리케이션 이미지를 확인
011) docker image inspect -f '{{.Config.Labels}}' diamol/ch11-numbers-api:v3-build-local
012) map[build_number:0 build_tag:local version:3.0]
- 004: 도커 컴포즈를 이용해 이미지를 빌드해도 도커 CL를 이용해 빌드한 이미지와 같은 결과를 얻는다.
-
011: 이미지 레이블을 확인, 레이블은 CI 파이프라인을 통해 컨테이너에서 실행된 빌드 과정을 추적하는 데 매우 유용하다.
-
컴포즈를 통해서 빌드하면 이미지 태그를 자동으로 생성한다.
- 컨테이너, 이미지, 네트워크 볼륨 등 대부분의 도커 리소스에는 레이블을 부여할 수 있으며, 리소스에 대한 추가 데이터에 키-값 쌍 형태로 저장된다.
- 레이블은 이미지에 포함시킬 수 있다는 점에서 이미지와 함께 사용할 때 특히 유용하다.
- CI 파이프라인을 통한 애플리케이션 빌드에서는 빌드 과정을 진행 중인 시점에 추적하거나 사후에 추적하는 것에 큰 도움이 된다.
빌드 인자와 이미지 레이블이 지정된 Dockerfile 스크립트의 예
- ARG:
- 이미지를 빌드하는 시점에만 유효한 환경 변수 값을 설정
- LABEL:
- Dockerfile 스크립트에 정의된 키-값 쌍을 빌드되는 이미지에 적용
# ch11/exercises/numbers/numbers-api/Dockerfile.v4
001) # 애플리케이션 이미지
002) FROM diamol/dotnet-aspnet
003)
004) ARG BUILD_NUMBER=0
005) ARG BUILD_TAG=local
006)
007) LABEL version="3.0"
008) LABEL build_number=${BUILD_NUMBER}
009) LABEL build_tag=${BUILD_TAG}
010)
011) ENTRYPOINT ["dotnet", "Numbers.Api.dll"]
빌드 설정값과 재사용 가능한 인자가 적용된 컴포즈 파일
- context:
- 도커가 빌드 중에 사용할 작업 디렉터리에 대한 경로
- 보통은 docker image build 명령에서 맨 끝에 .를 붙이므로 현재 디렉터리가 사용된다.
- 상대 경로일 경우 컴포즈 파일의 경로를 기준으로 한다.
- dockerfile:
- Dockerfile 스크립트의 경로
- 상대 경로일 경우 context에서 지정된 경로를 기준으로 한다.
- args:
- 빌드 시에 전달할 인자.
- Dockerfile 스크립트에서 ARG 인스트럭션으로 정의된 키와 일치해야 한다.
- 이 애플리케이션의 Dockerfile 스크립트에는 모두 BUTLD_NUMBER와 BUILD_TAG 인자가 사용됐다.
- 여기서는 컴포즈 확장 필드를 사용해 값을 정의하고 블록 두 곳에 확장 필드를 병합했다.
001) x-args: &args
002) args:
003) BUILD_NUMBER: ${BUILD_NUMBER:-0}
004) BUILD_TAG: ${BUILD_TAG:-local}
005)
006) services:
007) numbers-api:
008) build:
009) context: numbers
010) dockerfile: numbers-api/Dockerfile.v4
011) <<: *args
012)
013) numbers-web:
014) build:
015) context: numbers
016) dockerfile: numbers-web/Dockerfile.v4
017) <<: *args
-
009: numbers 도커가 빌드 중에 사용할 작업 디렉터리, numbers 를 사용
-
굉장히 많은 곳에서 기본값을 볼 수 있을 텐데, 이 기본값은 CI 파이프라인 절차를 적용하려다 다른 워크플로를 적용하기 곤란한 일이 없도록 하기 위한 것이다.
- 어떤 방법으 로 빌드를 실행하든 빌드가 항상 같은 방식으로 수행되려면 Dockerfile 스크립트를 하나의 파일로 유지해야 한다.
- 컴포즈 파일에 기본값을 설정하면 CI 서버 외의 곳에서 빌 드를 실행하더라도 빌드가 성공할 수 있으며 Dockerfile 스크립트에 정의된 기본값은 빌드 실행에 컴포즈를 사용하지 않더라도 적용될 것이다.
실습 무작위 숫자 API 이미지를 평소와 같이 image build 명령으로 빌드하면 컴포즈 파일의 설정을 우회해 이미지의 레이블을 원하는 대로 바꿀 수 있다. 빌드가 성공하면 Dockerfile 스크립트에 정의된 기본값이 적용된다.
# numbers 디렉터리로 이동
➜ cd ./ch11/exercises/numbers
# Dockerfile 스크립트 경로와 빌드 인자를 지정해 이미지를 빌드한다.
➜ docker image build -f numbers-api/Dockerfile.v4 --build-arg BUILD_TAG=ch11 -t numbers-api .
=> exporting to image 0.0s
=> => naming to docker.io/library/numbers-api
# 레이블을 확인
➜ docker image inspect -f '{{.Config.Labels}}' numbers-api
map[build_number:0 build_tag:ch11 version:3.0]
- 이미지에 레이블이 전달되는 과정만으로 상당한 분량을 설명했는데, 그만큼 제대로 알고 있어야 하는 부분이다.
- docker image inspect 명령으로 이미지의 레이블을 확인하고 이 레이블을 따라 이미지가 빌드된 CI 작업을 추적해 정확히 어느 버전의 코드가 빌드된 것인지 확인할 수 있어야 한다.
- 어떤 환경에서 실행 중인 컨테이너라도 다시 소스 코드까지 역추적할 수 있는 감사 추적이다.