본문 바로가기
Docker (도커 교과서)

3. 도커 이미지 만들기

by programmer-ds 2024. 12. 15.

※ 예제 컨테이너 설명

  •  ch03-web-ping : Node JS 기반으로 특정 URL에 HTTP 요청을 보내는 동작을 하는 컨테이너
    • 환경 변수 사용
      • TARGET : 지정된 URL로 HTTP 요청

1 도커 허브에 공유된 이미지 사용하기

1.1 docker image pull 

도커 CLI를 통해 명시적으로 원하는 이미지 내려받기

docker pull diamol/ch03-web-ping 실행 결과

  • 하나의 이미지는 여러 이미지가 계층적으로 쌓인 형태로 저장된다
  • 따라서 ch03-web-ping Image 하나를 다운받았지만, 여러 Image가 다운 받아지는 것을 확인할 수 있음

Image를 Pull할 때, 도커가 가장 먼저 접근하는 저장소는 도커 허브이다. 이렇게 이미지를 제공하는 저장소를 레지스트리(registry)라고 하는데, 도커 허브는 무료로 제공되는 공개 레지스트리다.

 

1.2 docker container run -d --name web-ping diamol/ch03-web-ping

  • -d : 해당 플래그는 --detach의 축약형 (즉, 백그라운드로 동작)
  • --name : 컨테이너에 원하는 Name을 붙이고 이 이름으로 컨테이너를 지칭할 수 있음 (기존엔 랜덤한 Name)

docker container run -d --name web-ping diamol/ch03-web-ping 실행 후 docker container logs로 log 확인 결과 해

  • 해당 App은 blog.sixeyed.com 이라는 URL로 반복적인 요청을 보냄
  • 해당 App은 환경변수로 TARGET, METHOD, INTERVAL을 사용하고 있으며, 기본값을 사용 중 (blog.sixeyed.com도 기본값에 해당)

1.3 docker container run --env

--env 옵션을 사용하여 환경 변수를 변경할 수 있음

docker container run --env TARGET=google.com diamol/ch03-web-ping 실행 결과

  • Default로 사용하던 URL을 google.com으로 변경하여 google.com으로 HTTP 요청을 함

 

2. Dockerfile 작성하기

  • Dockerfile은 애플리케이션을 패키징하기 위한 간단한 스크립트다.
  • 일련의 인스트럭션으로 구성돼 있으며, 인스트럭션을 실행한 결과로 도커 이미지가 만들어짐

2.1 Dockerfile 예시

FROM diamol/node

ENV TARGET="blog.sixeyed.com"
ENV METHOD="HEAD"
ENV INTERVAL="3000"

WORKDIR /web-ping
COPY app.js .

CMD ["node", "/web-ping/app.js"]
  • FROM
    • 모든 이미지는 다른 이미지로부터 출발한다. 이 이미지는 diamol/node 이미지를 Base로 함
    • diamol/node 이미지는 web-ping 애플리케이션을 실행하는 데 필요한 Node.js가 설치돼 있음
  • ENV 
    • 환경 변수 값을 지정하기 위한 인스트럭션
    • 값을 지정하기 위해서는 [key] = "[value]" 형식을 사용
    • 해당 스크립트에서는 세 개의 환경 변수를 사용
  • WORKDIR
    • 컨테이너 이미지 파일 시스템에 디렉터리를 만들고, 해당 디렉터리를 작업 디렉터리로 지정하는 인스트럭션
    • 리눅스와 윈도 컨테이너 모두 구분자로 슬래시를 사용
    • 해당 예시에서는 /web-ping 디렉터리를 만든다
  • COPY
    • 로컬 파일 시스템의 파일 혹은 디렉터리를 컨테이너 이미지로 복사하는 인스트럭션
    • [원본 경로] [복사 경로] 형식으로 사용
    • 해당 예시에서는 app.js 파일을 이미지의 작업 디렉터리로 복사
  • CMD
    • 도커가 이미지로부터 컨테이너를 실행했을 때 실행할 명령을 지정하는 인스트럭션
    • 해당 예시에서는 Node.js 런타임이 애플리케이션을 시작하도록 app.js를 지정
  • 위 5개의 인스트럭션 말고도 다양한 인스트럭션이 존재

 

2.2 Docker 예제 파일

여기서 사용하는 예제는 길벗출판사에서 제공하는 예제 파일을 사용한다.

길벗출판사 깃허브

예제 파일 디렉터리 구조

 

3. 컨테이너 이미지 빌드하기

3.1 docker image build --tag

  • --tag : --tag의 인잣값(web-ping)는 이미지의 이름
  • 이어지는 인자(.)는 Dockerfile 및 이미지에 포함시킬 파일이 위치한 경로
  • .은 '현재 작업 디렉터리'를 뜻함

Dockerfile 스크립트로 이미지를 빌드하는 명령이다. build 명령을 입력하면 Dockerfile 스크립트에 포함된 인스트럭션이 차례로 실행되며 그 결과가 출력된다.

docker image build --tag web-ping . 실행 결과

  • 해당 명령은 Dockerfile과 app.js 파일이 있는 디렉터리에서 실행해야 함

 

3.2 docker image ls 'w*'

'w'로 시작하는 태그명을 가진 이미지 목록 확인

docker image ls 'w*' 실행 결과

 

3.3 방금 Build한 Image를 환경 변수를 설정하여 실행

docker container run -e TARGET=docker.com -e INTERVAL=5000 web-ping 실행 결과

  • 환경 변수로 TARGET과 INTERVAL을 새로 설정

 

4. 도커 이미지와 이미지 레이어 이해하기

4.1 docker image history

선택한 image의 히스토리 확인

docker image history web-ping 실행 결과

  • 한 줄마다 한 레이어에 대한 정보가 출력됨
  • CREATED BY 컬럼은 해당 레이어를 구성한 Dockerfile 스크립트의 인스트럭션
  • Dockerfile 인스트럭션과 이미지 레이어는 1:1 관계를 갖는다.

 

4.2 도커 이미지 레이어 설명

  • 도커 이미지는 이미지 레이어가 모인 논리적 대상이다. 레이어는 도커 엔진의 캐시에 물리적으로 저장된 파일이다.
  • 이미지 레이어는 여러 이미지와 컨테이너에서 공유된다.
  • 만약 Node.js App이 실행되는 컨테이너를 여러 개 실행한다면 이들 컨테이너는 모두 Node.js 런타임이 들어있는 이미지 레이어를 공유한다.

이미지 레이어가 논리적 대상인 도커 이미지를 구성하는 원리

 

  • diamol/node 이미지는 최소한의 운영체제 레이어와 Node.js 런타임을 포함한다.
  • 위에서 사용한 예시인 web-ping 이미지는 diamol/node 이미지를 기반으로 하기때문에 기반 이미지의 모든 레이어를 포함한다.

 

5. 이미지 레이어 캐시를 이용한 Dockefile 스크립트 최적화

조금 전 빌드한 web-ping 이미지에는 App이 구현된 js 파일이 있다. 해당 js 파일을 수정하고 이미지를 다시 빌드하면, 새로운 이미지 레이어가 생긴다.

도커의 이미지 레이어가 특정한 순서대로만 배치된다고 가정하기에, 이 순서 중간에 있는 레이어가 변경되면 변경된 레이어보다 위에 오는 레이어를 재사용할 수 없다.

 

5.1 docker image build -t web-ping:v2 . 

app.js 파일을 수정(맨 끝에 빈 줄 추가도 가능)하고 다시 Build하면 아래와 같은 출력 결과를 확인할 수 있다.

app.js 파일 수정 후 다시 빌드한 결과

  • [2/3]... 라인을 보면 CACHED로 이전에 캐시된 레이러를 재사용한다.
  • [3/3].. 라인을 보면 app.js가 수정되었기 때문에 CACHED를 확인할 수 없다.
  • 더 확실한 비교를 위해 아무 수정하지 않고 다시 Build를 해보자

수정하지 않고 다시 빌드한 결과

  • 위 결과와 다르게 여기서는 [3/3]도 CACHED 되는 것을 확인할 수 있다. (변경된 것이 없기 때문에)

 

5.2 Dockerfile 스크립트 최적화하기

FROM diamol/node

CMD ["node", "/web-ping/app.js"]

ENV TARGET="blog.sixeyed.com" \
    METHOD="HEAD" \
    INTERVAL="3000"

WORKDIR /web-ping
COPY app.js .
  • CMD 인스트럭션은 스크립트 마지막에 위치할 필요가 없다. 이 인스트럭션은 FROM 인스트럭션 뒤라면 어디에 배치해도 무방하다. (수정할 일이 많이 없을 것이므로 초반부에 배치)
  • ENV 인스트럭션 하나로 여러 개의 환경 변수를 정의할 수 있으므로 ENV를 합칠 수 있다.

 

 

+ 빌드 시, 중요하게 여길 내용

아래 두 가지는 Dockerfile의 인스트럭션을 잘 배치하고 App의 설정값을 컨테이너에서 받도록 하는 방법으로 달성할 수 있다.

  1. Dockerfile 스크립트의 최적화
  2. 다른 환경에도 App을 배포할 수 있도록 이식성 있는 이미지를 만드는 것

'Docker (도커 교과서)' 카테고리의 다른 글

2. 도커의 기본적인 사용법  (1) 2024.12.15
1. Docker 설치하기  (0) 2024.12.15
0. Docker Intro  (2) 2024.12.15