본문 바로가기

기록

[Docker] compose.yaml - services - <서비스이름> - build

build: 도커 컴포즈의 서비스를 빌드하기 위한 설정

로컬 기기에서 프로젝트의 실행을 목적으로 하는 도커 컴포즈 환경이라면 프로젝트의 빌드 및 리빌드에 필요한 정보가 필요하다. 또한 이 속성은 간단하게 한 줄로 프로젝트 배포 경로만 작성할 수도 있다. (build: ./webapp)

services:
  frontend:
    image: example/webapp
    build: ./webapp

 

이 작성된 항목을 보면, example/webapp 이라는 이미지를 현재 폴더 내에 있는 DockerFile에서 찾아서 사용하고, 사용할 프로젝트의 경로는 컴포즈 환경설정 파일이 있는 폴더 안에 있는 webapp 폴더이다.

 

간단하게 말하면 경로는 다음과 같다.

/프로젝트 폴더
- /compose.yaml
- /frontend.Dockerfile
- /webapp

 

조금 더 명확하게 파일과 폴더를 지정하는 방법도 있다.

services:
  frontend:
    image: example/webapp
    build:
      context: webapp
      dockerfile: ../frontend.Dockerfile

build 하위 속성 - context / dockerfile / dockerfile_inline

context 속성은 도커 파일이 있는 폴더의 경로를 의미하며, 깃 저장소를 입력하기도 한다. 또한, dockerfile은 도커 파일의 이름을 입력한다.

상대 경로를 사용하는 경우

services:
  myservice:
    build:
      context: .
      dockerfile: Dockerfile

절대 경로를 사용하는 경우

services:
  myservice:
    build:
      context: /path/to/context
      dockerfile: Dockerfile

깃 저장소를 사용하는 경우

services:
  myservice:
    build:
      context: git://github.com/user/repo.git#branch
      dockerfile: Dockerfile

 

dockerfile이 매우 단순한 경우에는 한줄로 입력할 수도 있지만, 속성이 늘어나는 경우에는 복잡해 지기 때문에 별도의 파일을 만드는 것을 추천한다.

도커파일 한줄로 작성하는 예시

services:
  myservice:
    build:
      context: .
      dockerfile_inline: |
        FROM ubuntu:20.04
        RUN apt-get update && apt-get install -y curl
        CMD ["curl", "https://example.com"]

build 하위 속성 - args

빌드 시, 필요한 속성을 정의할 수 있다.

build:
  context: .
  args:
    GIT_COMMIT: cdc3b19

 

이렇게 정의를 해 두면 도커파일에서 다음과 같이 불러와서 사용할 수 있다.

ARG GIT_COMMIT
ENV GIT_COMMIT=${GIT_COMMIT}

 

build 하위 속성 - ssh

빌드 시, 외부 또는 내부 저장소를 가져오는 경우에 사용하면 편리한 옵션이다. key 파일을 사용하여 저장소에 접근하여 프로젝트를 받아올 . 수있다.

build:
  context: https://github.com/<project>.git
  dockerfile: Dockerfile
  ssh:
    - target=github.com
      sshkey: ~/.ssh/github_private_key

build 하위 속성 - cache_from, cache_to

cache_to 속성은 현재 이미지의 캐시를 저장하는 옵션이고, cache_from은 이전에 빌드한 이미지에서 캐시를 가져와서 사용하는 옵션이다. 따라서 처음 만들 때, cache_to를 사용하여 빌드를 해 두고, 다음에 동일한 이미지를 만드는 경우에 cache_from을 사용하면 더 빨리 빌드를 할 수 있다.

services:
  myservice:
    build:
      context: .
      dockerfile: Dockerfile
    cache_to:
      - type=local,dest=/path/to/cache
services:
  myservice:
    build:
      context: .
      dockerfile: Dockerfile
      cache_from:
        - myservice:latest
        - type=local,src=path/to/cache

build 하위 속성 - additional_contexts

이 속성은 서비스가 빌드 되기 이전에 또다른 공통 서비스나 컴포넌트가 존재하는 경우에 미리 빌드를 할 수 있는 옵션이다. frontend, backend가 공통 컴포넌트인 shared-components를 사용하고 있다고 가정해보면, 다음과 같이 작성할 수 있다.

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    additional_contexts:
      - context: ./shared-components
        dockerfile: Dockerfile

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    additional_contexts:
      - context: ./shared-components
        dockerfile: Dockerfile

build 하위 속성 - extra_hosts

컨테이너에 추가적인 호스트 엔트리를 제공할 때 사용된다. 이 속성을 사용하면 컨테이너 내에서 특정 호스트 이름을 특정 IP 주소에 매핑할 수 있다.

version: '3.8'

services:
  myservice:
    image: myimage
    extra_hosts:
      - "host1:192.168.1.10"
      - "host2:192.168.1.11"

 

도커파일에서 다음과 같이 사용될 수 있다.

FROM ubuntu:20.04

# ping 명령어를 사용하여 호스트1 및 호스트2에 접근하는 예시
RUN apt-get update && apt-get install -y iputils-ping
RUN ping -c 3 host1
RUN ping -c 3 host2

build 하위 속성 - isolation

서비스의 컨테이너를 격리 수준을 설정하는 데 사용된다. default, hyperv, process 3가지 옵션이 존재한다.

version: '3.8'

services:
  myservice:
    image: myimage
    isolation: hyperv

default

특징

기본 격리 수준으로 Linux 컨테이너를 실행합니다. 이는 일반적으로 사용되는 격리 기술로서 Linux 컨테이너를 실행하는 데 사용됩니다. 컨테이너는 호스트와 동일한 네임스페이스를 공유하고 격리된 환경에서 실행됩니다.

 

적용 대상

주로 Linux 호스트에서 동작하는 경우에 사용됩니다. 

hyperv

특징

Windows 컨테이너를 실행할 때 사용되는 Hyper-V 격리 기술을 사용합니다. 이 격리 기술은 Windows 컨테이너를 실행할 때 사용되며, 컨테이너를 더 격리된 환경에서 실행하도록 보장합니다.

 

적용 대상

Windows 호스트에서 Windows 컨테이너를 실행할 때 사용됩니다. 

process

특징

호스트와 같은 네임스페이스를 공유하는 프로세스 격리를 사용합니다. 이 옵션은 컨테이너를 가상화하지 않고 호스트에서 직접 실행하는 것처럼 컨테이너를 실행합니다. 따라서 호스트의 리소스를 직접 공유하며 격리된 프로세스로 실행됩니다.

 

적용 대상

일반적으로 Linux 호스트에서 사용되며, 컨테이너를 완전히 격리되지 않고 호스트와 같은 네임스페이스를 공유하며 실행하고자 할 때 사용됩니다.

build 하위 속성 - privileged

이 속성은 Docker 컨테이너를 실행할 때 컨테이너에 호스트 시스템의 특권을 부여하는 옵션이다. 이 옵션을 사용하면 컨테이너가 호스트 시스템의 더 많은 권한을 갖게 되어, 일반적으로 보안에 취약한 상태가 된다. 이 속성은 일부 특수한 경우에만 필요하며, 보안 상의 이유로 가능한 한 사용을 피해야 한다.

 

특징

  • 컨테이너 내에서 모든 시스템 호출을 수행할 수 있다.
  • 컨테이너 내에서 호스트의 디바이스를 직접 액세스할 수 있다.
  • 컨테이너 내에서 호스트의 커널 모듈을 로드하고 언로드할 수 있다.
version: '3.8'

services:
  myservice:
    image: myimage
    privileged: true

build 하위 속성 - labels

서비스의 메타 데이터를 표현하는데 사용하는 속성이다.

version: '3.8'

services:
  myservice:
    image: myimage
    labels:
      com.example.description: "Accounting webapp"
      com.example.department: "Finance"
      com.example.label-with-empty-value: ""

build 하위 속성 - no_cache

이 속성은 이미지를 빌드할 때 캐시를 사용하지 않도록 설정하는 옵션이다. 기본적으로 도커는 이미지 빌드 시 이전 빌드에서 생성된 캐시를 사용하여 빌드 속도를 높이는 데 사용한다. 하지만, 이전 빌드에서 생성된 캐시를 사용하지 않고 새로운 이미지를 생성해야 할 경우가 있는데, 이 때 no_cache: true 옵션을 사용하여 도커에게 캐시를 사용하지 않도록 지시할 수 있다.

version: '3.8'

services:
  myservice:
    build:
      context: .
      dockerfile: Dockerfile
    no_cache: true

build 하위 속성 - pull

이 속성은 이미지를 가져올 때 항상 최신 버전을 가져오도록 설정하는 옵션이다. 기본적으로 도커는 이미지를 가져올 때 로컬에 이미지가 존재하면 해당 이미지를 사용한다. 하지만, 항상 최신 버전의 이미지를 가져와야 할 경우가 있는데, 이 때 pull: always 옵션을 사용하여 도커에게 항상 최신 버전의 이미지를 가져오도록 지시할 수 있다.

version: '3.8'

services:
  myservice:
    image: myimage:latest
    pull: always

build 하위 속성 - network

서비스가 사용할 네트워크를 지정하는 데 사용된다. 이 속성을 사용하면 서비스를 기본 네트워크가 아닌 사용자가 정의한 네트워크에 연결할 수 있다.

 

네트워크는 Docker 컨테이너 간의 통신을 가능하게 하는데, 컨테이너는 기본적으로 독립적인 네트워크를 가지며, 다른 컨테이너와 통신하기 위해서는 네트워크를 공유하거나 연결해야 한다. network 속성을 사용하여 서비스를 사용자 정의 네트워크에 연결하면 다음과 같은 장점이 있다.

  • 네트워크 분리: 서비스를 기본 네트워크와 분리하여 각각의 네트워크를 사용하여 서비스 간의 통신을 분리할 수 있다. 
  • 외부 네트워크 연결: 외부에서 생성한 네트워크를 사용하여 서비스를 실행할 수 있다. 
  • 고유한 네트워크 설정: 사용자 정의 네트워크에 대해 고유한 설정을 적용할 수 있다.

이 속성은 총 3가지 옵션이 있다.

host

host 옵션을 사용하면 컨테이너가 호스트의 네트워크 네임스페이스를 사용하도록 지정할 수 있다. 이 옵션을 사용하면 컨테이너가 호스트의 네트워크에 직접 연결되어 외부 네트워크와 동일한 네트워크를 사용할 수 있다. 이는 컨테이너가 호스트와 동일한 네트워크를 공유해야 할 때 유용하다.

none

none 옵션을 사용하면 컨테이너에 네트워크를 할당하지 않고 독립적인 네트워크 네임스페이스를 사용하도록 지정할 수 있다. 이 옵션을 사용하면 컨테이너가 네트워크 연결 없이 독립적으로 실행된다. 따라서 컨테이너 간의 통신이나 외부와의 통신이 필요하지 않은 경우에 유용하다.

<custom name>

네트워크의 이름을 지정할 때는 해당 네트워크를 정의하는 부분에서 정의한 이름을 사용해야 한다. 네트워크를 정의하는 부분에서는 networks 섹션을 사용하여 네트워크를 정의하고, 그 안에서 각 네트워크에 대한 이름과 옵션을 지정할 수 있다.

 

예를 들어, 다음과 같이 네트워크를 정의한 후에는 해당 네트워크의 이름을 network 속성에 사용할 수 있다

version: '3.8'

services:
  myservice:
    image: myimage
    network: mynetwork

networks:
  mynetwork:
    driver: bridge

build 하위 속성 - shm_size

이 옵션은 컨테이너 내의 공유 메모리 크기를 지정하는 데 사용된다. 공유 메모리는 컨테이너 내에서 프로세스 간에 메모리를 공유할 때 사용되며, 특히 그래픽 애플리케이션 등에서 사용된다. 이 옵션을 사용하여 공유 메모리 크기를 설정할 수 있다.

version: '3.8'

services:
  myservice:
    image: myimage
    shm_size: '2gb'

build 하위 속성 - target

서비스를 빌드할 때 사용되는 도커 빌드 레이어의 캐시를 지정하는 데 사용된다. 이 속성은 도커 빌드 시 사용되는 --target 옵션을 설정하는 데 사용되며, 특정 빌드 단계부터만 빌드를 수행할 수 있도록 한다.

version: '3.8'

services:
  myservice:
    build:
      context: .
      dockerfile: Dockerfile
      target: mytarget

 

위와 같이 mytarget 이라는 이름을 넣어 두었다면 도커 파일에서 다음과 같이 사용할 수 있다.

# syntax=docker/dockerfile:1.0.0
FROM baseimage AS mytarget
RUN some_command

FROM anotherimage AS final
COPY --from=mytarget /path/to/source /path/to/destination

 

이 속성을 쓰는 경우에는 다음과 같은 사례가 있다.

멀티스테이지 빌드

Dockerfile이 여러 개의 스테이지로 구성되어 있는 경우에는 특정 스테이지에서만 빌드를 수행해야 할 때 target 속성을 사용한다. 예를 들어, 런타임 환경과 빌드 환경을 분리하여 최종 이미지를 빌드하는 경우에는 빌드 스테이지와 런타임 스테이지를 구분하여 각각에 대한 빌드를 따로 수행할 수 있다.

의존성 캐시 활용

특정 스테이지의 의존성이 변경되지 않았을 때 이전에 빌드된 캐시를 활용하여 빌드 시간을 단축하고자 할 때 target 속성을 사용한다. 이를 통해 불필요한 작업을 최소화하고 빌드 속도를 향상시킬 수 있다.

빌드 파이프라인 최적화

빌드 파이프라인에서 특정 단계의 빌드만을 실행하여 특정 작업을 수행하고자 할 때 target 속성을 사용한다. 이를 통해 불필요한 작업을 생략하고 효율적으로 빌드를 관리할 수 있다.

커스텀 빌드 타겟

사용자 정의 빌드 타겟을 정의하여 특정 스테이지에서만 빌드를 수행하고자 할 때 target 속성을 사용한다. 이를 통해 Dockerfile 내에서 다양한 빌드 타겟을 지정하고 관리할 수 있다.

build 하위 속성 - secrets

이 속성은 도커 컴포즈에서 사용되는 옵션 중 하나로, 서비스에 보안적으로 민감한 정보를 제공하는 데 사용된다. 이 속성을 사용하여 암호, 키, 인증 정보 등과 같은 민감한 정보를 관리하고, 이를 컨테이너에 안전하게 전달할 수 있다.

 

최상위에 선언되는 secrets 속성에 상세한 옵션을 정의한 뒤, services - build 속성 내에서 가져와서 사용할 수 있다.

services:
  frontend:
    build:
      context: .
      secrets:
        - server-certificate # 이름으로 불러온 시크릿 파일
        
# 최상위 선언한 시크릿 파일
secrets:
  server-certificate:
    file: ./server.cert

 

조금 더 상세하게 작성하는 옵션은 uid, gid, mode 속성을 추가해서 표현할 수 있다.

 

여기서 uid, gid는 리눅스 시스템에서 정의된 사용자 아이디와 그룹 아이디 이고, mode는 맨 앞자리 수 0을 제외한 440 이 권한을 나타낸다.

frontend:
  build:
    context: .
    secrets:
      - source: server-certificate
        target: server.cert
        uid: "103"
        gid: "103"
        mode: 0440

build 하위 속성 - ulimit

이 속성은 서비스의 운영체제 수준의 리소스 제한을 설정하는 데 사용된다. 이는 리눅스 운영체제에서 사용되는 ulimit 명령어와 유사한 역할을 한다. 주로 서비스가 사용하는 자원의 한계를 설정하여 서비스의 안정성을 보장하고 시스템 리소스를 효율적으로 관리하기 위해 사용된다. 예를 들어, 메모리나 파일 디스크립터 등의 리소스를 제한하는 데 사용된다.

 

위의 예시에서는 myservice 서비스의 파일 디스크립터 제한을 설정하고 있다. nofile은 파일 디스크립터를 나타내며, soft와 hard는 각각 소프트한 제한과 하드한 제한을 설정한다.

services:
  myservice:
    image: myimage
    ulimits:
      nofile:
        soft: 65536
        hard: 65536

 

build 하위 속성 - platforms

이 속성은 서비스가 지원하는 플랫폼 아키텍처를 설정하는 데 사용된다. 이 속성은 다중 플랫폼 이미지를 사용하여 서비스를 배포하거나, 특정 아키텍처에 최적화된 이미지를 선택하여 사용하는 데 유용하다.

services:
  myservice:
    image: myimage
    platforms:
      - linux/arm64

 

위의 예시에서는 myservice 서비스가 linux/arm64 아키텍처를 지원하는 이미지를 사용한다고 명시하고 있다. 이렇게 설정함으로써 해당 서비스는 arm64 아키텍처에 최적화된 이미지를 사용하여 실행될 것이다. 이러한 속성들은 도커 컴포즈 파일에서 서비스의 동작을 제어하고 관리하는 데 사용된다.