본문 바로가기
Framework and Tool/Docker

Docker - build arguments

by ocwokocw 2023. 6. 28.

- 출처: https://docs.docker.com/build/guide/build-args/

 

- Change runtime versions

일반적으로 build 인자를 실질적으로 사용하는 경우는 build stage 에서 runtime version을 지정하는 경우이다. 우리가 작성한 Dockerfile은 golang:1.20-alpine 을 기본 image로 사용하고 있다. 만약 다른 Go version을 사용해서 application을 build 하고 싶다면 어떻게 해야할까? 가장 직관적으로는 Dockerfile 내의 version을 갱신해주면 되지만 이런 방법은 매우 불편하고 비효율적이다.

 

# syntax=docker/dockerfile:1
ARG GO_VERSION=1.20
FROM golang:${GO_VERSION}-alpine as base
WORKDIR /src

...

 

FROM 지시어에 ARG 로 선언한 GO_VERSION build 인자를 끼워넣었다. default 값으로는 1.20을 설정하였는데 만약 build 인자를 받지 않으면 golang:1.20-alpine 으로 변환된다. 특정 Go version을 지정해서 build 하고 싶다면 --build-arg flag를 사용하면 된다.

buildme % docker build --build-arg="GO_VERSION=1.19" .
[+] Building 12.0s (14/14) FINISHED
 => [internal] load build definition from Dockerfile                                                                            0.0s
 => => transferring dockerfile: 819B                                                                                            0.0s
 => [internal] load .dockerignore                                                                                               0.0s
 => => transferring context: 2B                                                                                                 0.0s
 => resolve image config for docker.io/docker/dockerfile:1                                                                      0.7s
 => CACHED docker-image://docker.io/docker/dockerfile:1@sha256:39b85bbfa7536a5feceb7372a0817649ecb2724562a38360f4d6a7782a409b1  0.0s
 => [internal] load .dockerignore                                                                                               0.0s
 => [internal] load build definition from Dockerfile                                                                            0.0s
 => [internal] load metadata for docker.io/library/golang:1.19-alpine                                                           0.7s
 => [internal] load build context                                                                                               0.0s
 => => transferring context: 67.39kB                                                                                            0.0s
 => [base 1/3] FROM docker.io/library/golang:1.19-alpine@sha256:470c8d0638c5b7007a6118baee531c30e0516a18e45b35bff1f8ab92cf8f89  6.3s
 => => resolve docker.io/library/golang:1.19-alpine@sha256:470c8d0638c5b7007a6118baee531c30e0516a18e45b35bff1f8ab92cf8f896d     0.0s
 ...

- Inject values

build arguments를 사용하면 build time에 프로그램 소스코드 값을 수정할 수 있다. 이는 특히 동적 정보를 넘겨줄때 유용한데 Go 에서는 linker flag 혹은 -ldflags를 사용하면 build시 외부 값을 취할 수 있다.

 

예제 코드에서 server application main 함수에는 version을 명시하면 app version을 출력하는 코드가 포함되어 있다.

// cmd/server/main.go
var version string

func main() {
	if version != "" {
		log.Printf("Version: %s", version)
	}

물론 version string 변수를 직접 수정할 수 있지만 이러면 release 마다 값을 수정해줘야 한다. Dockerfile을 수정해서 build-server stage에서 APP_VERSION build 인자를 추가하도록 하자. Go compiler는 build 인자 값을 코드의 변수 값으로 설정한다.

buildme % cat Dockerfile

...

FROM base as build-server
ARG APP_VERSION="v0.0.0+unknown"
RUN --mount=type=cache,target=/Users/user/go/pkg/mod \
  --mount=type=bind,target=. \
  go build -ldflags "-X main.version=$APP_VERSION" -o /bin/server ./cmd/server

...

buildme % docker build --target=server --build-arg="APP_VERSION=v0.0.1" --tag=buildme-server .
[+] Building 9.1s (15/15) FINISHED
 => [internal] load build definition from Dockerfile                                                                            0.0s
 => => transferring dockerfile: 892B                                                                                            0.0s

...

buildme % docker run buildme-server
2023/06/28 13:50:46 Version: v0.0.1
2023/06/28 13:50:46 Starting server...
2023/06/28 13:50:46 Listening on HTTP port 3000

code를 수정하지 않고 server를 띄운 결과 인자로 설정한 v0.0.1 을 출력한것을 확인할 수 있다.

'Framework and Tool > Docker' 카테고리의 다른 글

Swarm mode overview and concepts  (0) 2023.09.17
Build Context  (0) 2023.08.12
Docker - Mounts  (0) 2023.06.21
Docker - Multi stage  (0) 2023.06.20
Docker image and layer  (0) 2023.06.18

댓글